管理activity的生命周期
来源:互联网 发布:游光网络拉勾网 编辑:程序博客网 时间:2024/04/30 13:40
对于Android的app开发而言,深度理解activity的生命周期相当重要,只有理解了,你才可能开发出高效稳定的app.比如你的app什么时候加载数据,什么时候保护现场,什么时候恢复重建,什么时候释放必要的资源。下面就开始了解了。
1.有张activity的生命周期的”金字塔”流程图,
Activity有3种可以长期保持的状态,运行态。暂停态(ui部分可见,无法交互),停止态(ui完全不可见,无法交互),
销毁activity,一般activity都会走完整个生命周期函数。但是有一种情况是如果在activity的oncreate中就调用了finish, 在这种情况下,系统会立刻调用 onDestroy(),而不调用任何其他 生命周期方法。
有关在activity的相应生命周期应该做的事情:
在onCreate()中,该方法只会出现被调用一次,用来实现定义用户界面并且可能实例化某些类范围变量。
在onResume()中,初始化需要在只有在获得用户焦点情况下的事情。
在onPause()中,停止动画或其他可能消耗CPU 的进行之中的操作;提交未保存的更改,但仅当用户离开时希望永久性保存此类更改(比如电子邮件草稿);释放系统资源,比如广播接收器、传感器手柄(比如GPS) 或当您的Activity暂停且用户不需要它们时仍然可能影响电池寿命的任何其他资源。避免在这里执行CPU 密集型工作,比如向数据库写入信息,因为这会拖慢向下一Activity过渡的过程(您应改为在onStop()期间执行高负载关机操作。
在onStop()中,一旦用户离开activity,就会调用该方法,但是在极端情况下,系统可能会终止整个进程,而不会再调用onDestory(),所以我们要在onStop()中释放可能引起泄露内存的资源非常重要,您应使用onStop() 执行更大、占用更多CPU 的关闭操作,比如向数据库写入信息。
在OnDestory()中,因为您通常应已使用onStop() 释放大多数您的资源,到您接收对onDestroy() 的调用时,大多数应用无需做太多操作。 此方法是您清理可导致内存泄露的资源的最后一种方法,因此您应确保其他线程被销毁且其他长期运行的操作(比如方法跟踪)也会停止。
2.恢复activity
上面的过程是用户正常操作时,程序必然要走过的正常流程。
但是常常有这种情况,例如转屏,程序处于后台时系统因为内存不足,程序activity被系统销毁等等。由于系统因系统局限性(而非正常应用行为)而销毁Activity,尽管Activity 实际实例已不在,系统会记住其存在,这样,如果用户导航回实例,系统会使用描述Activity被销毁时状态的一组已保存数据创建Activity的新实例。 系统用于恢复先前状态的已保存数据被称为“实例状态”,并且是 Bundle 对象中存储的键值对集合。
默认情况下,系统会使用 Bundle 实例状态保存您的Activity布局(比如,输入到EditText 对象中的文本值)中有关每个View 对象的信息。为了Android 系统恢复Activity中视图的状态,每个视图必须具有android:id 属性提供的唯一ID。这些都是系统帮我们做了,但是如果想恢复一些其他的东西,就必须我们自己手动做了。
流程图,
要保存有关Activity状态的其他数据,您必须替代onSaveInstanceState() 回调方法。当用户要离开Activity并在Activity意外销毁时向其传递将保存的Bundle 对象时,系统会调用此方法。 如果系统必须稍后重新创建Activity实例,它会将相同的Bundle 对象同时传递给onRestoreInstanceState() 和onCreate() 方法
销毁activity时,保存额外数据:
static final String STATE_SCORE = "playerScore";static final String STATE_LEVEL = "playerLevel";...@Overridepublic void onSaveInstanceState(Bundle savedInstanceState) { // Save the user's current game state savedInstanceState.putInt(STATE_SCORE, mCurrentScore); savedInstanceState.putInt(STATE_LEVEL, mCurrentLevel); // Always call the superclass so it can save the view hierarchy state super.onSaveInstanceState(savedInstanceState);}重新创建activity时,恢复数据:@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Always call the superclass first // Check whether we're recreating a previously destroyed instance if (savedInstanceState != null) { // Restore value of members from saved state mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL); } else { // Probably initialize members with default values for a new instance } ...}或者public void onRestoreInstanceState(Bundle savedInstanceState) { // Always call the superclass so it can restore the view hierarchy super.onRestoreInstanceState(savedInstanceState); // Restore state members from saved instance mCurrentScore = savedInstanceState.getInt(STATE_SCORE); mCurrentLevel = savedInstanceState.getInt(STATE_LEVEL);}
3.
3.处理运行时变更;
您可能会遇到这种情况:重启应用并恢复大量数据不仅成本高昂,而且给用户留下糟糕的使用体验。 在这种情况下,您有两个其他选择:
a方法的说明,通过保留 Fragment来减轻重新初始化 Activity的负担。此片段可能包含对您要保留的有状态对象的引用。当 Android系统因配置变更而关闭 Activity时,不会销毁您已标记为要保留的 Activity的片段。您可以将此类片段添加到 Activity以保留有状态的对象。
<span style="font-size:18px;">扩展 Fragment 类并声明对有状态对象的引用。public class RetainedFragment extends Fragment { // data object we want to retain private MyDataObject data; // this method is only called once for this fragment @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // retain this fragment setRetainInstance(true); } public void setData(MyDataObject data) { this.data = data; } public MyDataObject getData() { return data; }}添加到activity,重启activity时使用fragmentmanager检索片段public class MyActivity extends Activity { private RetainedFragment dataFragment; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // find the retained fragment on activity restarts FragmentManager fm = getFragmentManager(); dataFragment = (DataFragment) fm.findFragmentByTag(“data”); // create the fragment and data the first time if (dataFragment == null) { // add the fragment dataFragment = new DataFragment(); fm.beginTransaction().add(dataFragment, “data”).commit(); // load the data from the web dataFragment.setData(loadMyData()); } // the data is available in dataFragment.getData() ... } @Override public void onDestroy() { super.onDestroy(); // store the data in the fragment dataFragment.setData(collectMyLoadedData()); }}</span>
b方法的说明,自行处理配置变更
自行处理配置变更可能导致备用资源的使用更为困难,因为系统不会为您自动应用这些资源。 只能在您必须避免Activity因配置变更而重启这一万般无奈的情况下,才考虑采用自行处理配置变更这种方法,而且对于大多数应用并不建议使用此方法。
要声明由 Activity 处理配置变更,请在清单文件中编辑相应的 <activity>元素,以包含 android:configChanges属性以及代表要处理的配置的值。android:configChanges属性的文档中列出了该属性的可能值(最常用的值包括"orientation" 和"keyboardHidden",分别用于避免因屏幕方向和可用键盘改变而导致重启)。您可以在该属性中声明多个配置值,方法是用管道| 字符分隔这些配置值。
在onConfigurationChanged自行处理变更。
- 管理Activity的生命周期
- 管理Activity的生命周期
- Activity的生命周期管理
- 管理Activity的生命周期
- 管理Activity的生命周期
- 管理activity的生命周期
- activity的生命周期管理。
- 管理Activity的生命周期
- 管理Activity的生命周期
- 4.0 Activity的生命周期管理
- 关于Activity生命周期的管理
- Training--管理activity的生命周期
- 管理Activity的生命周期(1)
- Android Activity---管理Activity的生命周期
- Android Activity---管理Activity的生命周期
- Android Training - Activity生命周期的管理
- 【Android开发】管理Activity的生命周期(1)
- Activity生命周期的管理(序)
- 梳理struts2-面试题
- 指针与数组的区别
- python从0单排二
- 判断二叉树是否是平衡二叉树
- harbor 中 使用 push 上传镜像时候 显示 没有认证
- 管理activity的生命周期
- iOS解析json的4种方法
- iOS: SegmentControl 实现页面切换的四种方法
- Facade(外观模式)
- 梳理js-工作原理
- linux内核升级
- 梳理css-运行原理
- hdu 5414 CRB and String(字符串模拟)
- 企业管理授权指南(一)-前言