2012年8月24日金曜日

Application#onTerminate()がコールされない


(Activityではなく)Application単位でresume/pauseのハンドリングが可能か調査を行いました。
結論からいうと、frameworksからコールされる明示的なモジュールはありませんでした。


で、気になったのがApplication#onTerminate()というモジュール。
Android Developerには以下のように記載されています。

http://developer.android.com/reference/android/app/Application.html#onTerminate()

This method is for use in emulated process environments. It will never be called on a production Android device, where processes are removed by simply killing them; no user code (including this callback) is executed when doing so.

そう、Androidデバイスでは呼ばれることがないと書かれています。
じゃあ、何のために存在するのでしょう?

Application#onTerminate()をコールする箇所をgrepすると、ActivityThread.javaにありました。

1
2
3
4
5
6
case EXIT_APPLICATION:
    if (mInitialApplication != null) {
        mInitialApplication.onTerminate();
    }
    Looper.myLooper().quit();
    break;


この処理が行われるのは、ActivityThread#scheduleExit()の内部からhandleメッセージが発行されたとき。

ActivityThread#scheduleExit()をコールするのは、以下のActivityManagerService.javaの2モジュール。


1
2
private final boolean attachApplicationLocked(IApplicationThread thread, int pid)
final void trimApplications()

モジュール内の処理を見てみると、以下のような処理でした。
1
2
3
4
5
6
7
8
9
10
11
if (app.pid > 0 && app.pid != MY_PID) {
    EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
            app.processName, app.setAdj, "empty");
    Process.killProcessQuiet(app.pid);
} else {
    try {
        app.thread.scheduleExit();
    } catch (Exception e) {
        // Ignore exceptions.
    }
}
ActivityThread#scheduleExit()をコールする条件は次の場合。
  • PIDが0未満
  • PIDがMY_PID(= System Process)


System Processと同じApplicationの場合、コールするみたいなんです。
そんなApplicationってありえるのでしょうか。。。


このソースを見る限り、商品として発売されているAndroidデバイスでは呼ばれないことは確実ですね。

0 件のコメント:

コメントを投稿