AMSの停止Activity
3748 ワード
Activityの起動中、AMSは対応するアプリケーションプロセスstop Activityに通知せず、pause Activityのみであった.AMS内部には、アクティブメモリ管理メカニズムが提供されている.すなわち、AMSは、現在実行されているActivityの状態に基づいて、システムメモリが不足している場合に優先度の低いメモリを殺すが、優先度の高低の判断では、Activityに異なる重みを与える必要がある.この重みは、実行、停止、破棄など、Activityの状態である.これは、Activityが停止に関連する3つのコールバックonPause,onStop,onDestroyを提供している理由であり、異なるコールバックは異なるタイミングで発生し、AMSが現在のActivityの一時停止とユーザーのインタラクションを望んでいる場合、onPauseコールバックを実行し、AMSがこのActivityの重み値をstop状態に変更することを望んでいる場合、onStopコールバックを実行し、AMSがバックグラウンドでActivityを殺す準備をしている場合、onDestroyコールバックを実行する.
Activityのプロセスを停止
が発生するタイミングは異なります.pauseはターゲットActivityが起動する前に発生し、stopはターゲットActivityが起動した後の に発生します.コールバックActivityの異なる関数 は変調方式が異なり、pauseはamsが意図的に呼び出したものであり、stopは意図的に呼び出したものではない.
TU 10-14
Activityのプロセスを停止
1.resume固有のActivityの場合、ターゲット・プロセスのActivity ThreadがhandleResumeActivityを実行すると、IdleHandlerオブジェクトが作成され、メッセージ・キューに追加されます. if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
2.この時点でActivity ThreadはActivityを起動するすべての作業を完了しており、次にIdleステータスであるため、いくつかのIdle動作を実行でき、Idlerクラス内部処理関数はactivityIdleメソッドを呼び出す private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
ensureJitEnabled();
return false;
}
}
3.activityIdleはstopActivity Lockedに最終的に呼び出されます
1.HistoryRecordのintentにFLAG_が含まれているかどうかを確認するACTIVITY_NO_HISTORY、ある場合はrequestFinishActivity Lockedを呼び出してActivityオブジェクトを破棄します.FLAG_ACTIVITY_NO_HISTORYは、このフラグの役割は、mHistoryにActivityを出現させないこと、すなわちA->B->Cのような使い捨てである、Bの起動フラグにそのフラグが含まれている場合、B 2ではなくCから戻る後もAを実行し続けることである.ない場合は、現在実行中のActivityが停止するActivityと同じかどうかを判断し、同じ場合はsetFocusedActivity Locked 3を呼び出す.resumeKeyDispatchLockedを呼び出し、停止するActivityがユーザメッセージを受信することを一時的に許可する.setAppVisibilityを呼び出して停止するActivity 5を非表示にします.呼び出しscheduleStopActivityは、ターゲットプロセスのActivity Threadに非同期メッセージを送信し、ターゲットプロセスに指定されたActivityの停止を通知します.
4.メッセージはhandleStopActivityで処理する
TU 10-3 handleStopActivityの内部フロー
1.performStopActivity Inner 1.1を呼び出す:パラメータinfoが空の場合、AMSがActivityを停止するときにActivityの説明とサムネイルを取得することを示すため、コールバックonCreateDescriptionとcrateThumbnailBitmap 1.2:コールバックonStopメソッドは、デフォルトでは何もしない.updateVisibilityメソッドを呼び出すと、pauseの処理中に、Activityメッセージの配信を遮断するだけで、そのActivityに対応するウィンドウは依然として表示された状態であり、stopの意味には、そのウィンドウ3が表示されないことが含まれる.Activity Stoppedを呼び出し、AmsにそのActivityを停止したことを報告し、AMS側では関数内部実装は主にtrimApplicationを呼び出して一定のメモリ回収作業を行う.
区別する
if (!r.onlyLocalRequest) {
r.nextIdle = mNewActivities;
mNewActivities = r;
if (localLOGV) Slog.v(
TAG, "Scheduling idle handler for " + r);
Looper.myQueue().addIdleHandler(new Idler());
}
private class Idler implements MessageQueue.IdleHandler {
@Override
public final boolean queueIdle() {
ActivityClientRecord a = mNewActivities;
boolean stopProfiling = false;
if (mBoundApplication != null && mProfiler.profileFd != null
&& mProfiler.autoStopProfiler) {
stopProfiling = true;
}
if (a != null) {
mNewActivities = null;
IActivityManager am = ActivityManagerNative.getDefault();
ActivityClientRecord prev;
do {
if (a.activity != null && !a.activity.mFinished) {
try {
am.activityIdle(a.token, a.createdConfig, stopProfiling);
a.createdConfig = null;
} catch (RemoteException ex) {
}
}
prev = a;
a = a.nextIdle;
prev.nextIdle = null;
} while (a != null);
}
if (stopProfiling) {
mProfiler.stopProfiling();
}
ensureJitEnabled();
return false;
}
}
TU 10-14