Androidを支える技術<II> 5.5, 5.6章
日付:3/28
章:5.5 , 5.6
調査者:iNoma.icon
章のまとめ
どんな内容が書かれているか?
ActivityThreadの主要メソッド3つの掘り下げ
main()
5.4章で解説した
attach()
5.5章で解説
handleMessage()
5.6章で解説
5.5章 attach( )メソッドとApplication Contextの誕生
attach()メソッドで行われること
概要
ActivityManagerServiceに対して、ActivityThread自身をアプリのプロセスとして管理するように依頼する
実装
ActivityManagerServiceのattachApplication()の引数にActivityThread自身を渡して呼ぶ
ActivityManagerServiceによるアプリの管理
ActivityManagerServiceがApplicationThreadを通して以下の2メソッドを呼ぶ
bindApplication()
命名の統一を考えるなら「scheduleBindApplication()」
Binderドライバ越しにapkの情報を取得し、handleBindApplication()に渡す
scheduleLauchActivity()
Activityの生成を依頼する
名前の通り
handleBindApplication()がやっていること
Application Contextインスタンスの生成と初期化
handleMessageから受け取ったmsgに入っているapkの情報を元に行う
Application Contextとは?
apkファイルと紐づいた情報が欲しい時に触るオブジェクト
役割
apkへのパスの保持(カプセル化)
apkの中のデータを扱うものの取得
例
AssetManger
クラスローダー
apkからクラスをロード
Applicationインスタンスの作成
カスタムのApplicationクラスが指定されていた場合のみ
attach()メソッドの呼び出しスタック
attach()周りのメソッドコール群は、ややこしい!!!
呼び出される順番を整理しておこう
呼び出しスタック外観(インデント順にネストiNoma.icon)
ActivityThread::attach()
ActivityThread::bindApplication()
ActivityThread::handleBindApplication()
LoadedApk::makeApplication()
Instrumentation::newApplication()
ActivityStackSupervisor::attachApplicationLocked()
ActivityStackSupervisor::realStartActivityLocked()
ActivityThread::scheduleLauchActivity()
5.6 ActivityThreadのhandleMessage( )
handleMessage()
概要
ActivityThreadの3つの重要なメソッドの一つ
UIスレッドから呼ばれる
厳密には内部クラスH(Handlerのインスタンス)が持つメソッド
Activityのライフサイクル関連の処理が行われる
ライフサイクルのコールバックについて知りたい時はココ
メッセージIDの定義
Hのクラス定義内でstatic finalのintとして定義
例
LAUNCH_ACTIVITY = 100;
PAUSE_ACTIVITY = 101;
ライフサイクルのコールバックメソッドの名前と対応しているねiNoma.icon
メッセージの名前に応じて、scheduleXX()とhandleXX()を定義することになっている
table:メッセージIDに応じたメソッドの名前
説明 実際の名前
メッセージID LAUNCH_ACTIVITY
メッセージ送信メソッド scheduleLaunchActivity()
実際に処理を行うメソッド handleLaunchActivity()
handleMessage()内でIDでswitch-case文
対応するhandleXX()が呼ばれる
scheduleXX()
上記のメッセージを送信するメソッド群
ActivityManagerServiceからBinder越しで呼ばれる
スレッドが異なる
引数をmsgに格納してsendMesseage()を呼ぶだけ
ActivityとContextの誕生
handleXX()の処理の具体例を確認
handleLaunchActivity()の処理を追う
code:handleLaunchActivity.java
private void handleLaunchActivity(ActivityClientRecord r) {
// ActivityやContextの作成、onCreate()等の呼び出し
Activity a = performLaunchActivity(r);
// onResume()の呼び出し
handleResumeActivity(r.token, false, r.isForward,
!r.activity.mFinished && !r.startsNotResumed);
}
performLaunchActivity()が実質的にActivityの生成を行なっているねiNoma.icon
code:performLaunchActivity.java
private Activity performLaunchActivity(ActivityClientRecord r) {
// 起動しようとしているActivityのapkクラスファイルも読み込めるクラスローダーを取得
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
// ❶Activity誕生はここ!
Activity activity = mInstrumentation.newActivity(
cl, r.intent.getComponent().getClassName(), r.intent);
// これは通常はキャッシュのApplicationが返ってくるだけ
Application app = r.packageInfo.makeApplication(false, mInstrumentation);
// ❷Context誕生はここ!
Context appContext = createBaseContextForActivity(r, activity);
// ❸ContextをActivityにattach()
activity.attach(appContext, this, getInstrumentation(), r.token,
r.ident, app, r.intent, r.activityInfo, title, r.parent,
r.embeddedID, r.lastNonConfigurationInstances, config,
r.referrer, r.voiceInteractor);
// ❹onCreate()を呼び出す
mInstrumentation.callActivityOnCreate(activity, r.state);
// Bundleがある場合は(再生成の場合は)
if (r.state != null) {
// ❺onRestoreInstanceState()を呼び出す
mInstrumentation.callActivityOnRestoreInstanceState(activity, r.state);
}
// ❻onPostCreate()を呼び出す
mInstrumentation.callActivityOnPostCreate(activity, r.state);
}
mInstrumentationはActivityの対応メソッドを間接的に呼び出すだけ
単体テストのために作られた
かなりライフサイクルに紐づくコールバックメソッドたちの名前が見えて、楽しいね
そういえばこの辺の実際のソースコードってどこで見れるんだろiNoma.icon*3
H(Handler)のメッセージ概観
ActivityThreadが処理するメッセージは色々あるぞ!見てみよう
table:Activity関連メッセージID
LAUNCH_ACTIVITY (Activityを)起動する
PAUSE_ACTIVITY pause状態にする
STOP_ACTIVITY_SHOW Activityをstop状態にする。一部が画面に見えている状態(少し小さめのActivityなどが上に載った場合)
STOP_ACTIVITY_HIDE Activityをstop状態にする。このActivityは画面から全部隠れるケース
SHOW_WINDOW Windowが可視になった時に来る。ViewツリーのDecorViewをvisibleにする
HIDE_WINDOW Windowが不可視になった時に来る。ViewツリーのDecorViewをinvisibleにする
RESUME_ACTIVITY Activityをresumeする
SEND_RESULT Activityに結果を返す。startActivityForResultで呼ばれて戻ってきた時に呼ばれるonActivityResultを呼び出すメッセージ
DESTROY_ACTIVITY Activityを破棄する
table:SDKのService関連メッセージID
CREATE_SERVICE サービスの作成
BIND_SERVICE サービスのbind処理(bindService()呼び出しの処理。onBind()が呼ばれる)
UNBIND_SERVICE サービスのunbind処理
SERVICE_ARGS startServiceでのサービスの引数処理(onStartCommand( )呼び出し)
STOP_SERVICE サービスを終了する
table:その他の重要メッセージID
BIND_APPLICATION アプリの起動時のプロセスの初期化で呼ばれる。InstrumentationやApplicationインスタンスを作成したりする
EXIT_APPLICATION アプリを終了する。Looperのquit( )呼び出しをしてloop( )メソッドから抜ける
NEW_INTENT launchModeのsingleTaskなどのように新しくインスタンスを作らないケースで呼ばれるonNewIntent( )処理を行う
RECEIVER Receiverを作ってonReceive( )を呼ぶ
CONFIGURATION_CHANGED いろいろなコンフィグレーションの変更通知
LOW_MEMORY メモリ不足の時にやってくる。onLowMemory( )を呼び出したりSQLite等のキャッシュを解放したりする。API Level 14以上では下記のonTrimMemory( )を代わりに使うことが推奨されている
TRIM_MEMORY メモリを解放するよう依頼するonTrimMemory( )を呼び出す。引数で指示された段階に応じてキャッシュなどのリソースを解放していく。onTrimMemory( )で十分に解放することが推奨されている
応用
code:sample.kt
質疑応答