2012/10/08

disableForegroundDispatch()のcallがmustである理由を知りたい

一度気になると、なかなか忘れられないというところがある。
なぜ、onPause()が終わるまでにdisableForegroundDispatch()を呼び出さないといけないのだろう?


まずは、NfcAdapter.java。

public void disableForegroundDispatch(Activity activity) {
    ActivityThread.currentActivityThread().unregisterOnActivityPausedListener(activity,
            mForegroundDispatchListener);
    disableForegroundDispatchInternal(activity, false);
}

まず、unregisterOnActivityPausedListener()を呼んでいる。
引数にしているmForegroundDispatchListenerは、こんな定義だ。

OnActivityPausedListener mForegroundDispatchListener = new OnActivityPausedListener() {
    @Override
    public void onPaused(Activity activity) {
        disableForegroundDispatchInternal(activity, true);
    }
};

深追いしないが、名前からするとonPause()が呼ばれるようなタイミングになったら通知を受けるようなやつ(Listener)なんだろう。
中にはメソッドが1つあって、これがonPause()だ。中ではdisableForegroundDispatchInternal()を呼び出すだけ。

disableForegroundDispatchInternal()は、disableForegroundDispatch()の中でも呼ばれている。
違いは第2引数がtrueかfalseか。
仮引数名が"force"なので、強制的に無効にするかどうかのようだ。
何を持って「強制的」かというと、メインスレッドかどうかのようだ。
disableForegroundDispatch()の説明に「メインスレッドから呼べ」といっているのは、このことなのだろう。

 

強制的でも何でもonPause()が呼ばれたら無効にしてくれるんだったら、別にわざわざdisableを呼び出さなくてもいいんじゃないの、と思った。
前回「試したけど違いがわからん」といったのは、この強制的な手段が働いたからなのだろう。
それで十分やん!

 

とあさはかに考えそうだったが、disableForegroundDispatch()との違いはunregisterOnActivityPausedListener()の有無だ。
ここに秘密が隠されているのでは?


さっきのmForegroundDispatchListenerは、enableForegroundDispatch()で登録されて、disableForegroundDispatch()で登録解除されている。

何に対して登録/解除するかというと、ActivityThreadのmOnPauseListenersだ。
と、さも知ってるかのように書いたが、知らない。
名前からすると、onPause()を実行するときに呼び出すOnActivityPausedListenerの集合なんだろう。

この、よそ様の集合に登録しているから、最後はちゃんと解除しなさいよ、ということなのだろう。
onPause()が完了するまでに、という制限は、この集合がonPause()時に呼び出すためのものだからということか。

 

なんとなくわかった気がする。


やはり、解除しないまま呼び先がなくなったときの挙動が気になる。

どちらかというと、解除されてないからGCが作動せず、メモリに残り続ける、ということになるのかな。
Javaは詳しくないが、そんな感じだったような気がする。
Androidだからメモリがなくなれば有無を言わさないのかもしれないが、それまでは居座るのかもね。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。