androidソース解析(二十四)-->onSaveInstanceState実行タイミング
11717 ワード
Activityの起動プロセスを分析し、Activityのライフサイクルも分析しました.ライフサイクルメソッドの1つとして、onSaveInstanceStateメソッドがあります.今日は、onSaveInstanceStateメソッドの実行タイミングについて説明します.一部の学生はActivityのonSaveInstanceStateの方法にあまり詳しくないかもしれませんが、ここでは簡単に紹介します.onSaveInstanceStateメソッドはActivityのメンバーメソッドで、主にActivity破棄時にActivity関連のオブジェクト情報を保存するために使用されますが、その実行タイミングは私たちがアクティブに呼び出すのではなく、Androidシステムのframeworkが呼び出すのを手伝っています.その呼び出すタイミングはandroidシステムの紹介を参照してください.
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via {@link #onCreate} or {@link #onRestoreInstanceState}.
onSaveInstanceStateメソッドは、Activityがkillされるときに実行されることがわかります.O(∩∩)Oははは~は、以前説明した内容とあまり合っていないかもしれませんが、onSaveInstanceStatexメソッドはActivityが破棄されやすいときに実行されるという文章を見たことがあります.では、ここではActivityが破棄されたときにonSaveInstanceStateメソッドが実行されると言っているのに、具体的な状況はどうなっているのでしょうか.具体的にソースコードを見てみましょう.はは.
Activityのライフサイクルメソッドを解析することにより,onSaveInstanceStateメソッドはonPauseメソッドの後にonStopメソッドの前に実行されることが分かった.ここではまずonPauseメソッドのソースコードロジックを見てみましょう.
ActivityはonPauseメソッドを実行するときにActivity ThreadのhandlePauseActivityメソッドをコールバックします.よく知らない人は「Activityの起動プロセス」を参照してください.http://blog.csdn.net/qq_23547831/article/details/51224992「Activityライフサイクルについて詳しく説明しています.
では、まず具体的に見てみましょう.handlePauseActivityのソース:
メソッドボディでは、いくつかの他の操作を実行する以外に、handlePauseActivityメソッドボディでperformPauseActivityメソッドを呼び出します.このメソッドは、コールバックpauseActivity操作を具体的に実行する方法です.このように、performPauseActivityメソッドの実装を見てみましょう.
performPauseActivityメソッドでは、Activity ClientRecordが空かどうかを最初に判断し、performPauseActivityメソッドのリロードメソッドが呼び出されることがわかります.
ここではcallCallActivity OnSaveInstanceStateメソッドが呼び出され、名前を見るとここでコールバックすべきはActivityのonSaveInstanceStateメソッドであることがわかりますが、ここで実行する前に条件判断があり、まずここのActivityがfinishされているかどうかを判断します.このときonPauseメソッドを実行したばかりであるべきであるためここでのmFinished変数はfalseであるため、callCallActivity OnSaveInstanceStateメソッドを実行するにはsaveState変数で判断する必要がある限り、ここでのsaveStateメソッドはperformPauseActivityメソッドで渡されていると判断する..では、performPauseActivityメソッドを呼び出すときにsaveState変数がどのように割り当てられているかを見てみましょう.私たちのhandlePauseActivityメソッドに戻って、performPauseActivityメソッドがどのように呼び出されているかを見てみましょう.
saveState boolean変数はr.isPreHoneycombメソッドによって与えられていることがわかります.ここでは、IsPreHoneycombメソッドがどのように実現されているかを見てみましょう.
Appが設定targetSdkバージョン番号がandroid versionCode 11、すなわちandroid 3より小さいことがわかります.0の場合はtrue、その他の場合はfalse、つまりAppで設定したtargetVersionがandroid 3より大きい場合です.0のときにcallCallActivity OnSaveInstanceStateメソッドが実行されます.では、callCallActivity OnSaveInstanceStateメソッドがどのように実現されているかを見てみましょう.
メソッドボディは主にmInstrumentationのcallActivity OnSaveInstanceStateメソッドを呼び出していることがわかります.それなら、callActivity OnSaveInstanceStateメソッドを見てみましょう.
ここでメソッドボディにはActivityのperformSaveInstanceStateメソッドがコールバックされています..
ここでActivityのonSaveInstanceStateメソッドがコールバックされていることがわかり、一連のメソッドコールバックを経てonSaveInstanceStateメソッドが実行されます.
これにより、onPauseメソッドのみを実行する場合、targetVersionを設定ことによってonSaveInstanceStateメソッドを実行するかどうかを制御するのが一般的である、targetVersionCodeがandroid 3より大きい場合である.0の場合、onSaveInstanceStateメソッドはデフォルトでは実行されません.
次に、ActivityがonStopメソッドを実行するときにonSaveInstanceStateメソッドが実行されるかどうかを見てみましょう.前に分析したActivityの起動プロセスを通じて、ActivityがonStopメソッドを実行するとActivity ThreadのhandleStopActivityがコールバックされることを知っています.このように、handleStopActivityメソッドの実装を見てみましょう.
次に、メソッドperformStopActivityメソッドでperformStopActivityメソッドが呼び出されていることを発見しました.performStopActivity Innerメソッドの実装を引き続き見てみましょう.
onSaveInstanceStateを呼び出すかどうかをsaveState変数で制御するかを確認できますが、ここでのsaveState変数はperformStopActivity Innerメソッド呼び出し時に渡され、handleStopActivityメソッドのperformStopActivity Inner呼び出しに関するコードに戻ります.
ここでは直接trueとして値を伝え、Activityのstopメソッドを実行すると必ずonSaveInstancesStateメソッドを実行します.
まとめ onSaveInstanceStateメソッドはActivityのライフサイクルメソッドで、主にActivity破棄時に情報を保存するために使用されます. ActivityがonPauseメソッドのみを実行する場合(Activity aが透明Activity bを開く場合)App設定targetVersionがandroid 3より大きい場合.0ではonSaveInstanceStateメソッドは実行されません. ActivityがonStopメソッドを実行すると、ソースコードを解析することによってonSaveInstanceStateを呼び出すメソッドがtrueに直接伝達されることがわかり、onSaveInstanceStateメソッドが実行されます.
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via {@link #onCreate} or {@link #onRestoreInstanceState}.
onSaveInstanceStateメソッドは、Activityがkillされるときに実行されることがわかります.O(∩∩)Oははは~は、以前説明した内容とあまり合っていないかもしれませんが、onSaveInstanceStatexメソッドはActivityが破棄されやすいときに実行されるという文章を見たことがあります.では、ここではActivityが破棄されたときにonSaveInstanceStateメソッドが実行されると言っているのに、具体的な状況はどうなっているのでしょうか.具体的にソースコードを見てみましょう.はは.
Activityのライフサイクルメソッドを解析することにより,onSaveInstanceStateメソッドはonPauseメソッドの後にonStopメソッドの前に実行されることが分かった.ここではまずonPauseメソッドのソースコードロジックを見てみましょう.
ActivityはonPauseメソッドを実行するときにActivity ThreadのhandlePauseActivityメソッドをコールバックします.よく知らない人は「Activityの起動プロセス」を参照してください.http://blog.csdn.net/qq_23547831/article/details/51224992「Activityライフサイクルについて詳しく説明しています.
では、まず具体的に見てみましょう.handlePauseActivityのソース:
private void handlePauseActivity(IBinder token, boolean finished,
boolean userLeaving, int configChanges, boolean dontReport) {
ActivityClientRecord r = mActivities.get(token);
if (r != null) {
//Slog.v(TAG, "userLeaving=" + userLeaving + " handling pause of " + r);
if (userLeaving) {
performUserLeavingActivity(r);
}
r.activity.mConfigChangeFlags |= configChanges;
performPauseActivity(token, finished, r.isPreHoneycomb());
// Make sure any pending writes are now committed.
if (r.isPreHoneycomb()) {
QueuedWork.waitToFinish();
}
// Tell the activity manager we have paused.
if (!dontReport) {
try {
ActivityManagerNative.getDefault().activityPaused(token);
} catch (RemoteException ex) {
}
}
mSomeActivitiesChanged = true;
}
}
メソッドボディでは、いくつかの他の操作を実行する以外に、handlePauseActivityメソッドボディでperformPauseActivityメソッドを呼び出します.このメソッドは、コールバックpauseActivity操作を具体的に実行する方法です.このように、performPauseActivityメソッドの実装を見てみましょう.
final Bundle performPauseActivity(IBinder token, boolean finished,
boolean saveState) {
ActivityClientRecord r = mActivities.get(token);
return r != null ? performPauseActivity(r, finished, saveState) : null;
}
performPauseActivityメソッドでは、Activity ClientRecordが空かどうかを最初に判断し、performPauseActivityメソッドのリロードメソッドが呼び出されることがわかります.
final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,
boolean saveState) {
...
if (!r.activity.mFinished && saveState) {
callCallActivityOnSaveInstanceState(r);
}
...
}
ここではcallCallActivity OnSaveInstanceStateメソッドが呼び出され、名前を見るとここでコールバックすべきはActivityのonSaveInstanceStateメソッドであることがわかりますが、ここで実行する前に条件判断があり、まずここのActivityがfinishされているかどうかを判断します.このときonPauseメソッドを実行したばかりであるべきであるためここでのmFinished変数はfalseであるため、callCallActivity OnSaveInstanceStateメソッドを実行するにはsaveState変数で判断する必要がある限り、ここでのsaveStateメソッドはperformPauseActivityメソッドで渡されていると判断する..では、performPauseActivityメソッドを呼び出すときにsaveState変数がどのように割り当てられているかを見てみましょう.私たちのhandlePauseActivityメソッドに戻って、performPauseActivityメソッドがどのように呼び出されているかを見てみましょう.
performPauseActivity(token, finished, r.isPreHoneycomb());
saveState boolean変数はr.isPreHoneycombメソッドによって与えられていることがわかります.ここでは、IsPreHoneycombメソッドがどのように実現されているかを見てみましょう.
public boolean isPreHoneycomb() {
if (activity != null) {
return activity.getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.HONEYCOMB;
}
return false;
}
Appが設定targetSdkバージョン番号がandroid versionCode 11、すなわちandroid 3より小さいことがわかります.0の場合はtrue、その他の場合はfalse、つまりAppで設定したtargetVersionがandroid 3より大きい場合です.0のときにcallCallActivity OnSaveInstanceStateメソッドが実行されます.では、callCallActivity OnSaveInstanceStateメソッドがどのように実現されているかを見てみましょう.
private void callCallActivityOnSaveInstanceState(ActivityClientRecord r) {
r.state = new Bundle();
r.state.setAllowFds(false);
if (r.isPersistable()) {
r.persistentState = new PersistableBundle();
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state,
r.persistentState);
} else {
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
}
メソッドボディは主にmInstrumentationのcallActivity OnSaveInstanceStateメソッドを呼び出していることがわかります.それなら、callActivity OnSaveInstanceStateメソッドを見てみましょう.
public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,
PersistableBundle outPersistentState) {
activity.performSaveInstanceState(outState, outPersistentState);
}
ここでメソッドボディにはActivityのperformSaveInstanceStateメソッドがコールバックされています..
final void performSaveInstanceState(Bundle outState) {
onSaveInstanceState(outState);
saveManagedDialogs(outState);
mActivityTransitionState.saveState(outState);
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onSaveInstanceState " + this + ": " + outState);
}
ここでActivityのonSaveInstanceStateメソッドがコールバックされていることがわかり、一連のメソッドコールバックを経てonSaveInstanceStateメソッドが実行されます.
これにより、onPauseメソッドのみを実行する場合、targetVersionを設定ことによってonSaveInstanceStateメソッドを実行するかどうかを制御するのが一般的である、targetVersionCodeがandroid 3より大きい場合である.0の場合、onSaveInstanceStateメソッドはデフォルトでは実行されません.
次に、ActivityがonStopメソッドを実行するときにonSaveInstanceStateメソッドが実行されるかどうかを見てみましょう.前に分析したActivityの起動プロセスを通じて、ActivityがonStopメソッドを実行するとActivity ThreadのhandleStopActivityがコールバックされることを知っています.このように、handleStopActivityメソッドの実装を見てみましょう.
private void handleStopActivity(IBinder token, boolean show, int configChanges) {
ActivityClientRecord r = mActivities.get(token);
r.activity.mConfigChangeFlags |= configChanges;
StopInfo info = new StopInfo();
performStopActivityInner(r, info, show, true);
if (localLOGV) Slog.v(
TAG, "Finishing stop of " + r + ": show=" + show
+ " win=" + r.window);
updateVisibility(r, show);
info.activity = r;
info.state = r.state;
info.persistentState = r.persistentState;
mH.post(info);
mSomeActivitiesChanged = true;
}
次に、メソッドperformStopActivityメソッドでperformStopActivityメソッドが呼び出されていることを発見しました.performStopActivity Innerメソッドの実装を引き続き見てみましょう.
private void performStopActivityInner(ActivityClientRecord r,
StopInfo info, boolean keepShown, boolean saveState) {
...
if (!r.activity.mFinished && saveState) {
if (r.state == null) {
callCallActivityOnSaveInstanceState(r);
}
}
...
}
onSaveInstanceStateを呼び出すかどうかをsaveState変数で制御するかを確認できますが、ここでのsaveState変数はperformStopActivity Innerメソッド呼び出し時に渡され、handleStopActivityメソッドのperformStopActivity Inner呼び出しに関するコードに戻ります.
performStopActivityInner(r, info, show, true);
ここでは直接trueとして値を伝え、Activityのstopメソッドを実行すると必ずonSaveInstancesStateメソッドを実行します.
まとめ