android生命周期点击back键,Android之什么时候掉用onSaveInstance方法的时候(为什么按Home键盘会掉用,按Back不掉用)...

1、函数介绍

1)、onCreate(Bundle savedInstanceState) 方法

Activity 创建时回调 : 该方法会自动传入一个 Bundle 对象, 该 Bundle 对象就是上次被系统销毁时在 onSaveInstanceState 或者 onRestoreInstanceState 中保存的数据

-- 注意 : 只有是系统自动回收的时候才会保存 Bundle 对象数据;

-- Bundle 对象来源 : onCreate() 方法中的 Bundle 对象参数, 是在 onSaveInstance() 或者 onRestoreInstanceState() 方法中保存的 Bundle 对象;

2)、 onSaveInstanceState(Bundle outState) 方法

onSaveInstanceState函数是Activity的生命周期函数

outState 参数作用 :

数据保存 : Activity 声明周期结束的时候, 需要保存 Activity 状态的时候, 会将要保存的数据使用键值对的形式 保存在 Bundle 对象中;

恢复数据 : 在 Activity 的 onCreate()方法 创建 Activity 的时候会传入一个 Bundle 对象, 这个 Bundle 对象就是这个 outState 参数;

调用时机 : Activity 容易被销毁的时候调用, 注意是容易被销毁, 也可能没有销毁就调用了;

按下Home键 : Activity 进入了后台, 此时会调用该方法;

按下电源键 : 屏幕关闭, Activity 进入后台;

启动其它 Activity : Activity 被压入了任务栈的栈底;

横竖屏切换 : 会销毁当前 Activity 并重新创建;

onSaveInstanceState方法调用注意事项 :

用户主动销毁不会调用 : 当用户点击回退键 或者 调用了 finish() 方法, 不会调用该方法;

调用时机不固定 : 该方法一定是在 onStop() 方法之前调用, 但是不确定是在 onPause() 方法之前 还是 之后调用;

布局中组件状态存储 : 每个组件都 实现了 onSaveInstance() 方法, 在调用函数的时候, 会自动保存组件的状态, 注意, 只有有 id 的组件才会保存;

关于默认的 super.onSaveInstanceState(outState) : 该默认的方法是实现 组件状态保存的;

(3) onRestoreInstanceState(Bundle savedInstanceState) 方法 方法回调时机 : 在 Activity 被系统销毁之后 恢复 Activity 时被调用, 只有销毁了之后重建的时候才调用, 如果内存充足, 系统没有销毁这个 Activity, 就不需要调用;

-- Bundle 对象传递 : 该方法保存的 Bundle 对象在 Activity 恢复的时候也会通过参数传递到 onCreate() 方法中;

2、源码分析调用onSaveInstance函数的时候

1)、看下

ActivityThread.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;

}

}

再看

performPauseActivity方法

final Bundle performPauseActivity(IBinder token, boolean finished,

boolean saveState) {

ActivityClientRecord r = mActivities.get(token);

return r != null ? performPauseActivity(r, finished, saveState) : null;

}

再看掉用重载方法

performPauseActivity

final Bundle performPauseActivity(ActivityClientRecord r, boolean finished,

boolean saveState) {

...

if (!r.activity.mFinished && saveState) {

callCallActivityOnSaveInstanceState(r);

}

...

}我们知道

调用callCallActivityOnSaveInstanceState方法,看名称发现这里应该回调的是Activity的onSaveInstanceState方法,我们再看掉用这个函数的条件

!r.activity.mFinished && saveState如果activity没有掉用finish() 方法,mFinished的值就是false,如果需要进入这个函数,就需要后面的值saveState值为0,这里的

saveState是performPauseActivity方法传递过来的

performPauseActivity(token, finished, r.isPreHoneycomb());我们再看函数

r.isPreHoneycomb

public boolean isPreHoneycomb() {

if (activity != null) {

return activity.getApplicationInfo().targetSdkVersion

< android.os.Build.VERSION_CODES.HONEYCOMB;

}

return false;

}

App设置的targetSdk版本号小于android versionCode 11也就是android3.0的时候返回为true,其他的时候返回为false,也就是说当我们App设置的targetVersion大于android3.0的时候才会执行callCallActivityOnSaveInstanceState方法,然后接着看callCallActivityOnSaveInstanceState方法,如下

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);

}

}我们再去Instrumentation.java里面去看函数

callActivityOnSaveInstanceState

public void callActivityOnSaveInstanceState(Activity activity, Bundle outState,

PersistableBundle outPersistentState) {

activity.performSaveInstanceState(outState, outPersistentState);

}

我们再去Activity.java里面去看函数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方法。

接下来我们看下onStop方法是否会执行onSaveInstanceState方法,同理Actvitiy执行onStop方法会回调ActivityThread的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;

}我们再来看方法performStopActivityInner实现

private void performStopActivityInner(ActivityClientRecord r,

StopInfo info, boolean keepShown, boolean saveState) {

// Next have the activity save its current state and managed dialogs...

if (!r.activity.mFinished && saveState) {

if (r.state == null) {

callCallActivityOnSaveInstanceState(r);

}

}

if (!keepShown) {

try {

// Now we are idle.

r.activity.performStop();

} catch (Exception e) {

if (!mInstrumentation.onException(r.activity, e)) {

throw new RuntimeException(

"Unable to stop activity "

+ r.intent.getComponent().toShortString()

+ ": " + e.toString(), e);

}

}

r.stopped = true;

}

我们知道saveState穿进去为true,只要mFinished不是true就一定进入这个方法,所以只要在mFinished不为true,也就是没有调用finish()函数的前提下,就一定执行onSaveInstanceState方法,所以当App设置的targetVersion大于android3.0,没有调用finish函数的情况下,一定会调用onSaveInstanceState方法后再去调用onStop方法。

3、为什么按Home键盘会掉用onSaveInstance方法保存数据,按Back不掉用onSaveInstance方法保存数据

因为按下Home键盘没有调用 finish函数,如果targetVersion大于Androi3.0就一定执行

onSaveInstanceState方法,所以就保存数据了,如果按下返回键,会调用 finish方法,所有mFinished为true,所以不会掉用onSaveInstanceState方法,所以不会保存数据。

4、手机常见操作Activity生命周期状态变化来验证

写了一个简单的Activity,在每个Activity周期函数里面打印了相关的执行函数信息

1)、启动Activity

0818b9ca8b590ca3270a3433284dd417.png

2)、按下电源或者Home键

0818b9ca8b590ca3270a3433284dd417.png

3)、按亮电源键或者点击项目(一开启按了Home键)

0818b9ca8b590ca3270a3433284dd417.png

4)、按下返回键(back键盘)

0818b9ca8b590ca3270a3433284dd417.png

5、总结

1、onSaveInstanceState方法是Activity的生命周期方法,主要用于在Activity销毁时保存一些信息。

2、当Activity只执行onPause方法时(Activity a打开一个透明Activity b)这时候如果App设置的targetVersion大于android3.0则不会执行onSaveInstanceState方法。

3、当Activity执行onStop方法时,通过分析源码我们知道只要Activity没有执行finish函数一定会调用onSaveInstanceState的方法,然后再去掉用onStop方法。

onPause() -> onSaveInstanceState() -> onStop()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值