Android ソースコード読書会 第4回 Activity.java

というわけで、日本Androidの会福岡支部の中で、Android SDKソースコードを読む読書会(輪講)を隔週でやってまして、今回は第4回目です。Androidの中心とも言えるActivity.javaのライフサイクルを中心にソースコードを読み進めていきました。担当は @kenz_firespeed さんでした。

android.git.kernel.org Git - platform/frameworks/base.git/blob - core/java/android/app/Activity.java

まずはライフサイクルの整理


読みやすいので図解Androidのライフサイクルとプラットフォーム « Tech Boosterさんより引用

  • onStop(), onDestory()は場合によっては呼ばれない可能性があるのでスレッドの終了処理をここに書いちゃダメ。書くとしたらキャッシュの削除とかかな。
  • onCreate()はKillされないと呼ばれないので、ここに全ての初期化処理を書くと呼ばれない事がある。
  • onResume(), onPause()を中心に初期化、終了処理を書くと手堅い。でも、パフォーマンスに難があるので、少しずつ別メソッドに移すと無駄がないかも。
  • finish()を呼ぶと一気にonDestory()が呼ばれ、onPasuse(), onStop()などのライフサイクルは呼ばれないのでこれも注意。Activity.onCreate()のコメントに書いてた。
  • データを保持するBundleに保存するためのonSaveInstanceState(Bundle)とBundleから値を取得するonRestoreInstanceState(Bundle)がある。
  • このライフサイクルをメインに、オーバーライドできるメソッドは結構ある。

Activityはだれが管理しているのか。

ActivityThread.javaです。
android.git.kernel.org Git - platform/frameworks/base.git/blob - core/java/android/app/ActivityThread.java

だいたい以下の流れです。

ActivityThreadにLooperからMessageがhandleMessage(Message)経由で次々に送られてきます。Message.whatで呼び出し理由をswitchで判断してます。case ***:を見るとActivity起動時のLAUNCH_ACTIVITYなどが並んでます。(メモリーが減るとLOW_MEMORYが呼ばれるんだろうなぁ。ふむふむ)

 923         public void handleMessage(Message msg) {
 924             if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);
 925             switch (msg.what) {
 926                 case LAUNCH_ACTIVITY: {
 927                     ActivityClientRecord r = (ActivityClientRecord)msg.obj;
 928 
 929                     r.packageInfo = getPackageInfoNoCheck(
 930                             r.activityInfo.applicationInfo);
 931                     handleLaunchActivity(r, null);
 932                 } break;
 933                 case RELAUNCH_ACTIVITY: {
 934                     ActivityClientRecord r = (ActivityClientRecord)msg.obj;
 935                     handleRelaunchActivity(r, msg.arg1);
 936                 } break;
 937                 case PAUSE_ACTIVITY:
 938                     handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
 939                     maybeSnapshot();
 940                     break;

辿っていくと1611行目でmInstrumentation.callActivityOnCreate()でonCreateを呼んでます。その前後にsetThemeしてたりするので、Activityのライフサイクルの前後に何をしているのか理解できていいですね。

1605                 int theme = r.activityInfo.getThemeResource();
1606                 if (theme != 0) {
1607                     activity.setTheme(theme);
1608                 }
1609 
1610                 activity.mCalled = false;
1611                 mInstrumentation.callActivityOnCreate(activity, r.state);
1612                 if (!activity.mCalled) {
1613                     throw new SuperNotCalledException(
1614                         "Activity " + r.intent.getComponent().toShortString() +
1615                         " did not call through to super.onCreate()");
1616                 }

まとめ

ActivityThreadのソースコード読むのが楽しくて盛り上がったので、Activityを読む回は次回以降にまた行うことになりました。ライフサイクルがわかるとAndroidが可愛く見えてきますね。
あと、InstrumentationはAndroidのテストコード書くときに重要になるので覚えておきたいところです。

次回はIntent.javaです。Activity.startActivity(intent)からの処理を中心に進めていきます。

んじゃまた!