Android常见知识点之Activity
- Activity的生命周期
- onStart()和onResume()/onPause()和onStop()的区别
- Activity A启动另一个Activity B会回调哪些方法?如果Activity B是完全透明呢?如果启动的是一个Dialog呢?
- 谈谈onSaveInstanceState()方法?何时会调用?
- onSaveInstanceState()与onPause()的区别?
- 如何避免配置改变时Activity重建?
- 优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态?
- onNewIntent()调用时机?
- Activity启动模式的标记位
- 如何启动其他应用的Activity?
- Activity的启动过程?
- Activity的四种启动模式
Activity的生命周期
这是activity的生命周期流程图,如下
![](http://hi.csdn.net/attachment/201109/1/0_1314838777He6C.gif)
-
启动Activity:系统会先调用onCreate方法,然后调用onStart方法,最后调用onResume,Activity进入运行状态。
-
当前Activity被其他Activity覆盖其上或被锁屏:系统会调用onPause方法,暂停当前Activity的执行。
-
当前Activity由被覆盖状态回到前台或解锁屏:系统会调用onResume方法,再次进入运行状态。
-
当前Activity转到新的Activity界面或按Home键回到主屏,自身退居后台:系统会先调用onPause方法,然后调用onStop方法,进入停滞状态。
-
用户后退回到此Activity:系统会先调用onRestart方法,然后调用onStart方法,最后调用onResume方法,再次进入运行状态。
-
当前Activity处于被覆盖状态或者后台不可见状态,即第2步和第4步,系统内存不足,杀死当前Activity,而后用户退回当前Activity:再次调用onCreate方法、onStart方法、onResume方法,进入运行状态。
-
用户退出当前Activity:系统先调用onPause方法,然后调用onStop方法,最后调用onDestory方法,结束当前Activity。
-
onWindowFocusChanged方法:在Activity窗口获得或失去焦点时被调用,例如创建时首次呈现在用户面前;当前Activity被其他Activity覆盖;当前Activity转到其他Activity或按Home键回到主屏,自身退居后台;用户退出当前Activity。以上几种情况都会调用onWindowFocusChanged,并且当Activity被创建时是在onResume之后被调用,当Activity被覆盖或者退居后台或者当前Activity退出时,它是在onPause之后被调用。(例如程序启动时想要获取特定视图组件的尺寸大小,在onCreate中可能无法取到,因为窗口Window对象还没创建完成,这个时候我们就要在onWindowFocusChanged里获取)
-
onSaveInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,此方法会被调用;(2)在用户改变屏幕方向时,此方法会被调用;(3)在当前Activity跳转到其他Activity或者按Home键回到主屏,自身退居后台时,此方法会被调用。第一种情况我们无法保证什么时候发生,系统根据资源紧张程度去调度;第二种是屏幕翻转方向时,系统先销毁当前的Activity,然后再重建一个新的,调用此方法时,我们可以保存一些临时数据;第三种情况系统调用此方法是为了保存当前窗口各个View组件的状态。onSaveInstanceState的调用顺序是在onPause之前
-
onRestoreInstanceState:(1)在Activity被覆盖或退居后台之后,系统资源不足将其杀死,然后用户又回到了此Activity,此方法会被调用;(2)在用户改变屏幕方向时,重建的过程中,此方法会被调用。我们可以重写此方法,以便可以恢复一些临时数据。onRestoreInstanceState的调用顺序是在onStart之后
onStart()和onResume()/onPause()和onStop()的区别
1. onStart()和onResume():onStart界面可见不可交互,而是到onResume时界面可交互。
2. onPause()和onStop():onPause()时Activity失去焦点,但仍然可见(用于由一个Activity转到另一个Activity、设备进入休眠状态(屏幕锁住了)、或者有dialog弹出时),onStop()时Activity在后台,不可见(完全被另一个Activity挡住,或者程序后台运行,有对话框弹出时,这时底下的activity仍然可见,所以此时onStop不会被调用)
Activity A启动另一个Activity B会回调哪些方法?如果Activity B是完全透明呢?如果启动的是一个Dialog呢?
回调的方法:依次为----> A(onPause)—>B(onCreate)---->B(onStart)---->B(onResume)---->A(onStop),当启动一个透明的activity B时,生命周期为A(onPause)—>B(onCreate)---->B(onStart)---->B(onResume),此时不会调用A的onStop方法,如果启动的只是对话框,activity A的生命周期不会发生变化
谈谈onSaveInstanceState()方法?何时会调用?
onSaveInstanceState方法是在activity将要被kill的时候执行,这样的话将来某个时候能够恢复它的状态。一般下面几种情况会执行该方法:
- 从activity A中启动一个新的activity时;
- 屏幕方向切换时,例如从竖屏切换到横屏时;
注意:在屏幕切换之前,系统会销毁activity A,在屏幕切换之后系统又 会自动地创建activity A,所以onSaveInstanceState一定会被执行。 - 按下电源按键(关闭屏幕显示)时;
- 当用户按下HOME键,回到桌面时。
总结:onSaveInstanceState的调用遵循一个重要原则,即当系统“未经你许可”时销毁了你的activity,则onSaveInstanceState会被系统调用,这是系统的责任,因为它必须要提供一个机会让你保存你的数据,主动finish activity 时,不会调用该方法。另外,onSaveInstanceState()会在onPause()或onStop()之前执行,onRestoreInstanceState()会在onStart()和onResume()之间执行。屏幕方向切换时,Activity被系统销毁后重新建立,此时会调用onSaveInstanceState方法保存数据。方法执行过程为:
onPause –>onSaveInstanceState–>onStop–>onDestory–>onCreate(切换屏幕后重新创建Activity时调用的onCreate方法)–>onStart–>onRestoryInstanceState–>onResume。
onSaveInstanceState()与onPause()的区别?
- onsavedinstance(Bundle savedinstancestate)方法的触发时机,其典型的情景是按home键或者切换activity,这样的activity可能被销毁的场合,但是按back键退出程序,则不会调用此方法,适合保存一些非持久性的数据(即程序运行期间需要储存的数据)。
- onpause(),不管是可能销毁还是退出程序,都必须调用,适合保存持久性的数据,但是android本身没有为此方法提供bundle参数,因此我们可以选用做一个静态变量或者是提供一个sharedpreference作为数据载体。
如何避免配置改变时Activity重建
比如我们不想让 屏幕方向发生改变时Activity重建,那么只需在AndroidManfest.xml中对应的Activity标签中添加一句 android:configChanges=”orientation|screenSize”
优先级低的Activity在内存不足被回收后怎样做可以恢复到销毁前状态
可以覆写onSaveInstanceState()方法。onSaveInstanceState()方法接受一个Bundle类型的参数, 开发者可以将状态数据存储到这个Bundle对象中, 这样即使activity被系统摧毁, 当用户重新启动这个activity而调用它的onCreate()方法时, 上述的Bundle对象会作为实参传递给onCreate()方法, 开发者可以从Bundle对象中取出保存的数据, 然后利用这些数据将activity恢复到被摧毁之前的状态。注意:onSaveInstanceState()方法并不是一定会被调用的,因为有些场景是不需要保存状态数据的. 比如用户按下BACK键退出activity时, 用户显然想要关闭这个activity, 此时是没有必要保存数据以供下次恢复的,也就是onSaveInstanceState()方法不会被调用. 如果调用onSaveInstanceState()方法, 调用将发生在onPause()或onStop()方法之前。
onNewIntent()调用时机
前提:ActivityA已经启动过,处于当前应用的Activity堆栈中.
- 当ActivityA的LaunchMode为SingleTop时,如果ActivityA在栈顶,且现在要再 启动ActivityA,这时会调用onNewIntent()方法
- 当ActivityA的LaunchMode为SingleInstance,SingleTask时,如果已经ActivityA已经在堆栈中,那么此时会调用onNewIntent()方法
- 当ActivityA的LaunchMode为Standard时,由于每次启动ActivityA都是启动新的实例,和原来启动的没关系,所以不会调用原来ActivityA的onNewIntent方法
Activity启动模式的标记位
- FLAG_ACTIVITY_NEW_TASK :指定 Activity 以 singleTask 模式启动
- FLAG_ACTIVITY_SINGLE_TOP :指定 Activity 以 singleTop 模式启动
- FLAG_ACTIVITY_CLEAR_TOP :具备此标记为的 Activity 在启动时会将位于同一任务栈的所有位于它上面的 Activity 出栈,这个标记位一般会和 singleTask一起出现,singleTask 启动模式默认就具有此标记位的效果
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS :具有这个标记的 Activity 不会出现在历史 Activity 列表中
如何启动其他应用的Activity
- 通过自定义action启动:这种方式只需要在代码中设置一个action即可, 系统会自动过滤去找到这个action所对应的Activity
------------当前app代码:
Intent intent = new Intent();
//这里是采用的自定义action
intent.setAction(“transBundle.app”);
startActivity(intent);
-------------待启动APP 的activity在AndroidManifest.xml中的配置
<!- 需要配置对应的自定义action->
<activity
android:name=".MyActivity"
android:label="@string/app_name"
android:exported="true">
<intent-filter>
<action android:name="transBundle.app"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
-
通过在Intent中通过指定包名和类名来查找
ComponentName componetName = new ComponentName( "com.poynt.weibo", //这个是另外一个应用程序的包名 "com.poynt.weibo.ui.IndexActivity"); //这个参数是要启动的Activity的全路径名 try { Intent intent = new Intent(); intent.setComponent(componetName); startActivity(intent); } catch (Exception e) { Toast.makeText(getApplicationContext(), "可以在这里提示用户没有找到应用程序,或者是做其他的操作!", 0).show(); }
-
通过scheme启动,这个方法和方法1类似, 只是说增加了scheme参数, scheme更多的用于 在网页或者H5上来启动我们的APP, 比如在手机官网上通过scheme可以直接打开我们的app, 这里我们只是从APP用scheme启动另一个APP。
当前应用的代码:Uri uri = Uri.parse("app://my.test"); Intent intent = new Intent("transBundle.app", uri); startActivity(intent);
待打开APP的AndroidManifest配置
<activity
android:name=".MyActivity"
android:label="service"
android:exported="true">
<intent-filter>
<action android:name="transBundle.app"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="app" android:host="my.test"/>
</intent-filter>
</activity>
Activity的启动过程
Activity的四种启动模式
详见文章链接:启动模式