作者简介
微信公众号(高质量文章推送):走向全栈工程师
作者:陈博易
声明:本文是个人原创,未经允许请勿转载
商业合作请在微信公众号回复:联系方式
![](https://img.haomeiwen.com/i3376017/a9fe281a22841914.gif)
前言
1.我记得我实习的那会,面试官问我关于acitivity的现场如何恢复,我当时也就知道保存和取值的方法,今天就当复习了。
2.同时也希望大家帮小编一起分享给其他人,让小编的文章可以让更多人看到
环境以及工具
- Android项目:AndroidStudio3.0
整体步骤
- Activity中如何保存值,如何状态恢复
详细步骤
1. Activity中保存值,状态恢复
当Andriod系统由于某种原因回收了activity,这时会调用activity的onSaveInstanceState方法保存值
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//存值
outState.putString("test", "test");
Log.d("tag", "onSaveInstanceState:test ");
}
当Andriod重新创建activity,这时会调用activity的onRestoreInstanceState或者onCreate方法取出保存值
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//拿值,方式1
String test = savedInstanceState.getString("test");
Log.d("tag", "onRestoreInstanceState" + test);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
if (savedInstanceState != null) {
//拿值,方式2
String test = savedInstanceState.getString("test");
Log.d("tag", "onRestoreInstanceState" + test);
}
}
核心步骤解读
1. 模拟当前应用被系统回收
进入开发者选项,选中不保留活动。
开启选项后,启动目标程序页面,用Home键返回桌面,稍候几秒再次点击启动目标程序。
测试完毕后,最好将刚刚选中的不保留活动的选项恢复如初。
![](https://img.haomeiwen.com/i3376017/fb898672533f98ef.png)
知识盲点梳理
1. 何时回收当前应用activity
除了在栈顶的Activity,其他的Activity都有可能在内存不足的时候被系统回收,一个Activity越处于栈底,被回收的可能性就越大。
2. 何时onSaveInstanceState被执行
当某个activity变得“容易”被系统销毁时,该activity的onSaveInstanceState就会被执行,除非该activity是被用户主动销毁的,例如当用户按BACK键(手机下方的返回键)的时候。
分为以下几种情况:
- 从第一个界面跳转到第二个界面,第一个界面就会执行onSaveInstanceState
- 按下home键,运行多个其他程序,这时系统不确定会不会将该activity销毁,所以会执行onSaveInstanceState方法保存值。
- 关闭手机屏幕时
- 屏幕方向切换时,例如从竖屏切换到横屏时。(前提是androidMenifest.xml中对应activity标签没有配置)
<!--防止系统配置改变,重新创建Activity。常见场合:弹出软键盘、屏幕旋转-->
<activity
android:name=".Main2Activity"
android:configChanges="orientation|keyboardHidden|screenSize"></activity>
3. 为什么我们的UI界面的值不用我们自己保存也可以自动保存,状态恢复呢?
- 开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可),剩余的事情就可以自动完成了。如果没有为控件指定ID,则这个控件就不会进行自动的数据保存和恢复操作。(不相信的可以试试看)
- Android应用框架中定义的几乎所有的UI控件都恰当的实现了onSaveInstanceState()方法,因此当Activity被摧毁和重建时,这些UI控件会自动保存和恢复状态数据。
4. 为什么onSaveInstanceState 执行时机会在onStop之前呢?
小编也是写文章的时候再思考这个onSaveInstanceState是在什么具体时间被条用的,所以小编就开始深入跟进源码了![](https://img.haomeiwen.com/i3376017/83748271272b5cbe.png)
![](https://img.haomeiwen.com/i3376017/805fd33bd82fe955.png)
![](https://img.haomeiwen.com/i3376017/85336a107b62aaee.png)
![](https://img.haomeiwen.com/i3376017/048143985f94239e.png)
![](https://img.haomeiwen.com/i3376017/08c7fe351b609db3.png)
![](https://img.haomeiwen.com/i3376017/178438353563b066.png)
看到这里小编还是没看到什么东西。
只是知道了AppCompatActivity FragmentActivity SupportActivity 分别初始化了父类的onSaveInstanceState,关键这个onSaveInstanceState是时候被调用呢?
又发现了activity中的onSaveInstanceState被一个public的方法调用了。
![](https://img.haomeiwen.com/i3376017/3c8e348d9a0c8576.png)
终于到了最想看到的方法了。也不知道什么原因无法看到哪里调了performSaveInstanceState方法,如果有高人看到指点指点了。给我评论下,应该自己的源码导入姿势不大对吧。
![](https://img.haomeiwen.com/i3376017/191a1ee3d1bb92cf.png)
接下来的比较复杂,涉及到Activity启动流程在里面,本人目前也不是很清楚的,但是我比较清楚的是Activity的启动流程涉及ActivityThread与ActivityManagerService之间的通讯,实际上acitivty的启动分为应用进程端的启动和SystemServer服务进程端的启动的,而在应用进程端靠的是Intrumentation来执行一些方法的。
ActivityThread中的一些方法看着好像有点认识。和生命周期的一些方法有点像,因为perform带有执行的意思。
![](https://img.haomeiwen.com/i3376017/6ac9b727ec815f21.png)
![](https://img.haomeiwen.com/i3376017/8216002a01a67eda.png)
![](https://img.haomeiwen.com/i3376017/e0eb8ce9b23d1bc9.png)
核心的方法到了,从这里就可以看出onSaveInstanceState方法是在onStop方法之前执行的。
private void performStopActivityInner(ActivityClientRecord r,
StopInfo info, boolean keepShown, boolean saveState, String reason) {
...........................省去n行代码
// Next have the activity save its current state and managed dialogs...
//下一步将保存当前activity的状态
if (!r.activity.mFinished && saveState) {//activity还没finish并且save为true
if (r.state == null) {
callCallActivityOnSaveInstanceState(r);//调用callCallActivityOnSaveInstanceState
}
}
}
这里发现 mInstrumentation这个应用进程端的操作类调用了callActivityOnSaveInstanceState
![](https://img.haomeiwen.com/i3376017/8f64dae0aa68cc64.png)
答案好像出来了,这里就是activity.performSaveInstanceState
![](https://img.haomeiwen.com/i3376017/c3b9990825cd9e99.png)
这里是不是就和前面的activity的performSaveInstanceState首尾呼应了呢。
![](https://img.haomeiwen.com/i3376017/a62fb7c969075eac.png)
总结
Android源码解析请参考这个大神的,小编的水平还是没到这个水平的。
http://blog.csdn.net/qq_23547831/article/details/51224992
个人相关教程
各种大佬推荐的编程视频资源分享
postman使用 Android java后端 接口调试工具
Android抓包 Charles http接口调试
消息推送 Android java后端集成小米推送
如何导入简单的java项目-IntelliJ IDEA
请关注我(高质量文章推送)
关注微信公众号:走向全栈工程师
![](https://img.haomeiwen.com/i3376017/984d23bad2d5a87d.jpg)
网友评论