Android中Activity生命周期浅析
来源:互联网 发布:网络翻译招聘 编辑:程序博客网 时间:2024/06/04 23:27
编写不易,如有转载,请声明出处: 梦回河口:http://blog.csdn.net/zxc514257857/article/details/76686607
Activity形态
Activity是由Activity栈进行管理,当来到一个新的Activity后,此Activity将被加入到Activity栈顶,之前的Activity位于此Activity底部。Activity最大的特点就是拥有多种形态,在多种形态间进行切换,控制自己的生命周期
- Active/Running形态
此时,Activity处于Activity栈的栈顶,可见且可交互
- Paused形态
当Activity失去焦点,被一个新的非全屏的Activity或者透明的Activity放置在栈顶时(此时原Activity失去栈顶位置),Activity就转化为了paused形态。不可交互但所有状态信息,变量都还保持着,只有在系统内存极低的情况下才会被系统回收
- Stopped形态
当Activity失去焦点,且被一个新的全屏不透明的Activity覆盖,Activity就进入stopped形态。此时,Activity不再可见
- Killed形态
当Activity被系统回收掉或Activity从来没有创建过,Activity就处于Killed形态
Activity生命周期
图中详细给出了Activity整个生命周期的过程,以及在不同的状态期间相应的回调方法
从图中可以看出:
一个最简单的完整的Activity生命周期会按照如下顺序回调:onCreate() —> onStart() —> onResume() —> onPause() —> onStop() —> onDestroy() 。这称之为entire lifetime。在系统调用onCreate()之后,就会马上调用onStart(),然后继续调用onResume()完成启动,最后系统会调用onDestory()来结束一个Activity的生命周期让它回到Killed形态
由onStart() —> onResume() —> onPause(),一直到onStop()方法调用之前,这段生命周期内Activity都是被用户可见的。这称之为visible lifetime
由onResume()一直到onPause()方法调用之前,这段生命周期内Activity都是可以响应用户交互的(即前台的或者是可以获取焦点的)。这称之为foreground lifetime
由此我们可以知道:
invisible lifetime由onCreate() 、onStop() —> onDestory()阶段组成。background lifetime由 (除onResume()到onPause()方法调用之前这一阶段) 组成
一个应用程序在进程不被系统清除的情况下由后台恢复到前台,有两种方式: onPause() —> onResume() ,重新获取焦点;onStop() —> onRestart() —> onStart() —> onResume()
Activity生命周期有三个状态是稳定的,其他状态都是过渡状态,很快就会结束。Resumed状态 可见,可交互(最常见状态);Raused状态 不可交互,可见(失去栈顶);Stopped状态 不可交互,不可见(后台状态)
onCreate()中一般需要完成:创建基本UI元素;onResume() 中一般需要完成:重新初始化在onPause()中释放的资源;onpause()和onStop()中一般需要完成:清除Activity的资源,避免浪费,如Camera,sensor,Receiver等;onDestory()中一般需要完成:清除开启的线程
onSaveInstanceState()
- 来源
如果你的应用长时间处于Stopped状态,而且此时系统需要更多内存或者内存极为紧张时,系统就会回收你的Activity,而此时系统为了补偿你,会将Activity状态通过onSaveInstanceState()方法保存到Bundle对象中,当然你也可以增加额外的键值对存入Bundle对象以保存这些状态。当你需要重新创建这些Activity的时候,保存的Bundle对象就会传递到Activity的onRestoreInstanceState()方法与onCreate()方法中,这也就是onCreate()方法中参数——-Bundle savedInstanceState的来源(这里持怀疑态度,因为当我在onSaveInstanceState()方法中存入Bundle savedInstanceState参数后,只有在横竖屏切换时才走onCreate()和onRestoreInstanceState()方法取出数据,其他情况都无法取出)
- 调用时机
onSaveInstanceState()并不是每次当Acitivity离开前台时都会调用,如果用户使用finish()方法主动去结束一个Activity则不会调用。因为在这种情况下,用户的行为决定了不需要保存Activity的状态。通常onSaveInstanceState()只适合用于保存一些临时性的状态,而onPause()适合用于数据的持久化保存。Android系统已经默认实现了控件的状态缓存,以此来减少开发者需要实现的缓存逻辑
- 源码分析
onSaveInstanceState ()是在函数里面保存一些View有用的数据到一个Parcelable对象并返回。在Activity的onSaveInstanceState(Bundle outState)中调用View的onSaveInstanceState (),返回Parcelable对象,接着用Bundle的putParcelable方法保存在Bundle savedInstanceState中。当系统调用Activity的的onRestoreInstanceState(Bundle savedInstanceState)时,通过Bundle的getParcelable方法得到Parcelable对象,然后把该Parcelable对象传给View的onRestoreInstanceState (Parcelable state)。在的View的onRestoreInstanceState中从Parcelable读取保存的数据以便View使用
Activity中onCreate()源码实现
Activity中onSaveInstanceState(Bundle outState)源码实现
Activity中onRestoreInstanceState(Bundle savedInstanceState)源码实现
如果我们没有重写onSaveInstanceState()方法,此方法的默认实现会自动保存activity中的某些状态数据, 比如activity中各种UI控件的状态。android应用框架中定义的几乎所有UI控件都恰当的实现了onSaveInstanceState()方法,因此当activity被摧毁和重建时,这些UI控件会自动保存和恢复状态数据。比如EditText控件会自动保存和恢复输入的数据,而CheckBox控件会自动保存和恢复选中状态。开发者只需要为这些控件指定一个唯一的ID(通过设置android:id属性即可), 剩余的事情就可以自动完成了。如果没有为控件指定ID,则这个控件就不会进行自动的数据保存和恢复操作。由上所述, 如果我们需要重写onSaveInstanceState()方法,一般会在第一行代码中调用该方法的默认实现:super.onSaveInstanceState(outState)
- 重写时机
如果需要保存额外的数据时, 就需要重写onSaveInstanceState()方法。大家需要注意的是:由于onSaveInstanceState()方法方法不一定会被调用, 因此不适合在该方法中保存持久化数据, 例如向数据库中插入记录等,onSaveInstanceState()方法只适合保存瞬态数据,比如UI控件的状态,成员变量的值等,持久化数据应该当用户离开当前的 activity时,在 onPause() 中保存(比如将数据保存到数据库或文件中)。若是永久性值,则在onPause()中保存;若数量较大,则另开线程吧,别阻塞UI线程
代码验证
import android.content.Intent;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; // 何时会取出Bundle中的数据? // 后台到前台/锁屏/多界面应用切换/界面跳转 不会取 设置了"开发者选项"--->"不保留活动"就会取了 // 旋转屏幕会取 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG, "onCreate-->" + "创建!"); if(savedInstanceState != null){ String string = savedInstanceState.getString("Activity"); Log.i(TAG , "onCreate-->从Bundle中取出数据:" + string); } } @Override protected void onStart() { super.onStart(); Log.i(TAG, "onStart-->" + "可见!"); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume-->" + "获取焦点!"); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause-->" + "失去焦点!"); } @Override protected void onStop() { super.onStop(); Log.i(TAG, "onStop-->" + "不可见!"); // int a = 5/0; } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy-->" + "销毁!"); } @Override protected void onRestart() { super.onRestart(); Log.i(TAG, "onRestart-->" + "重新恢复可见!"); } @Override public void onBackPressed() { Intent intent = new Intent(MainActivity.this , SecondActivity.class); startActivity(intent); } // 何时会调用此onSaveInstanceState方法? // 后台到前台/锁屏/旋转屏幕/多界面应用切换/界面跳转 会调用 // 按back键销毁 不会调用 @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); String string = "Bundle中存储的数据!"; outState.putString("Activity" , string); Log.i(TAG, "onSaveInstanceState-->" + "保存数据在Bundle中!"); } @Override public void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); String string = savedInstanceState.getString("Activity"); Log.i(TAG , "onRestoreInstanceState-->从Bundle中取出数据:" + string); }}----------------------------------------------------------------------------------------import android.content.Intent;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;public class SecondActivity extends AppCompatActivity{ private static final String TAG = "SecondActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sec); Log.i(TAG, "onCreate-->" + "创建!"); } @Override protected void onStart() { super.onStart(); Log.i(TAG, "onStart-->" + "可见!"); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "onResume-->" + "获取焦点!"); } @Override protected void onPause() { super.onPause(); Log.i(TAG, "onPause-->" + "失去焦点!"); } @Override protected void onStop() { super.onStop(); Log.i(TAG, "onStop-->" + "不可见!"); } @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG, "onDestroy-->" + "销毁!"); } @Override public void onBackPressed() { Intent intent = new Intent(SecondActivity.this , MainActivity.class); startActivity(intent); finish(); }}
启动应用,进入MainActivity
MainActivity—>SecondActivity:
SecondActivity—>MainActivity:
以上验证了一个Activity的完整生命周期;两个Activity之间的跳转生命周期回调;Activity跳转时finish()的作用;
- 后台到前台/锁屏/多界面应用切换:
以上验证了后台到前台/锁屏/多界面应用切换/界面跳转会调用onSaveInstanceState(Bundle outState)方法,但不会因为内存不足而取出保存的数据
- 横竖屏切换:
以上验证了横竖屏切换可以保存也可以取出Bundle中的数据
- 设置了”开发者选项”—>”不保留活动”:
系统对不保留活动的描述就是:用户离开后即销毁每个活动,即只要应用不可见系统就会自动调用onDestory()方法,以上验证了,在设置了不保留活动的情况下,系统可以保存也可以取出Bundle中的数据
参考资料:http://www.cnblogs.com/lwbqqyumidi/p/3769113.html
http://blog.csdn.net/javazejian/article/details/51932562
———-因本人才疏学浅,如博客或Demo中有错误的地方请大家随意指出,与大家一起讨论,共同进步,谢谢!———-
- Android中Activity生命周期浅析
- Android activity的生命周期浅析
- Android之Activity生命周期浅析
- Android之Activity生命周期浅析
- Android中Activity生命周期
- Android中Activity生命周期
- Android中Activity生命周期
- Android之Activity生命周期浅析(一)
- Android之Activity生命周期的浅析(二)
- 【生命周期】Android中Activity的生命周期
- Activity的生命周期浅析
- activity生命周期浅析
- Activity的生命周期浅析
- Android中Activity的生命周期
- Android中Activity的生命周期
- Android中Activity的生命周期
- Android 中Activity的生命周期
- Android中Activity的生命周期
- 某款asp的cms程序注射漏洞
- GBDT(MART) 迭代决策树入门教程 | 简介
- Activity的四种启动模式和onNewIntent()
- Mybatis 批量插入返回 主键ID
- Custom Key Managers in JSSE
- Android中Activity生命周期浅析
- SQLite学习手册(在线备份)
- android 抛弃Mvc ,初尝 Mvp 模式
- HDU 2586 How far away (LCA模板题 树上点对间距离)
- nginx配置静态资源,访问返回403
- Laravel5.4 不同环境下 env 文件设置
- 暑期ssh框架之struts2学习笔记三
- 漫聊android适配动态权限机制
- 2017 Multi-University Training Contest