Activity进阶笔记
正常生命周期的方法
- onCreate:此方法在Activity创建的时候回调
- onRestart:此方法在Activity不可见之后,重新变为可见的过程中时候会回调
- onStart:此方法在Activity可见的时候回调,但是此时Activity处在后台,也就是说用户无法进行操作
- onResume:同样是可见的时候回调,而此时已经是在前台了,用户可以正常操作界面了
- onPause:从前台变为后台的时候,会被调用,比如用户启动了一个透明的Activity,那么之前的Activity就会调用onPause,进入后台。
- onStop:Activity不可见的时候会被调用,比如按下Home键,回到桌面,则会调用onPause和onStop
- onDestory:Activity被正常销毁的时候会被调用
在启动另外一个Activity的时候,会先调用onPause方法,然后调用第二个Activity的onCreate , onStart, onResume,然后再调用第一个的onStop方法。
所以,不能在onPause方法中进行耗时的操作,否则会影响第二个Activity的启动。同样,onStop也不应该太耗时,onDestory方法可以用来最终的释放资源。
Activity异常情况下的生命周期
-
当资源相关的系统配置发生改变Activity被杀死并重新创建
比如当屏幕尺寸发送改变的时候(旋转屏幕),Activity其实是被销毁了,并重新创建了一个Activity。
所以先会执行普通的销毁过程onPause->onStop->onDestory,但是在其中会有一步onSaveInstanceState,在onPause之后,用来保存view的状态。
然后重新启动的时候,会在onRestoreInstanceState里面恢复view之前的状态,此方法调用在onStart之后。
思考:不是异常情况下,
onSaveInstanceState
方法也会被调用,但是不会调用onRestoreInstanceState
方法。 -
如何防止重新创建Activity?
android:configChanges="orientation|screenSize"
在AndroidManifest中,为Activity配置此属性即可防止在翻转屏幕的重新创建Activity。取而代之的是会回调
onConfigurationChanged
方法 -
内存不足的时候,系统很可能会杀死在后台的Activity,生命过程与上面一样。
思考:系统杀死的时候似乎直接结束的进程,而不会走一遍销毁的生命周期。
Activity启动模式
四种启动模式:
设置启动模式:在AndroidManifest中为Activity设置launchMode=""
即可。
-
standard
这是默认的启动模式,被启动的Activity B如果是standard模式,那么B的新的实例会被创建并加入到启动它的任务栈的栈顶。(Service是没有任务栈的,所以通过Service启动的时候,会报错,要添加FLAG_ACTIVITY_NEW_TASK flag才能启动,这相当于是singleTask模式启动)
-
singleTop
与上面的类似,只不过如果B在栈顶,那么不会再创建新的实例。方法的调用:onPause->onNewIntent->onResume。如果B不在栈顶,则会创建新的实例。
-
singleTask
这是栈内复用模式。启动Activity的时候,会先查询是否已经存在了任务栈,如果不存在,那么会先创建任务栈,然后再创建实例压栈。如果已经存在,那么会直接在目标栈内寻找实例。如果存在实例,那么会将目标调到栈顶(其之上的会弹栈,也就是有clearTop的效果),如果不存在实例,那么会创建新实例并压栈。
-
singleInstance
这个是单实例模式。此模式的Activity只能单独位于一个任务栈中。所以,一旦创建,以后就不会创建新的Activity了,除非该Activity被销毁。
通过上面几种模式的总结,可以思考一个问题:APP的MainActivity适合哪种模式?
适合singleTask模式,因为我们在其他界面回到MainActivity,也就是主界面,那么其他的界面都应该被销毁,而不是按back键能够返回去。所以singleTask可以帮助我们clearTop。
如何指定任务栈?
在AndroidManifest中,为Activity设置android:taskAffinity=""
即可,里面填写的值不要与app包名一样,否则是同一个任务栈。默认的任务栈名称是包名。
Activity的Flags
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_SINGLE_TOP
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
隐式启动
IntentFilter匹配规则
intent-filter主要可以配置三个参数,action
,category
,data
.
一个intent只有同时匹配action
,category
,data
才算匹配成功
一个Activity可以配置多个intent-filter,只要匹配上了一个intent-filter就可以启动该Activity。
-
action
intent必须要指定一个action,不然会直接匹配失败。
只要匹配成功一个action即可。
-
category
一定要有一个值为
<category android:name="android.intent.category.DEFAULT"></category>
的category,不然intent会匹配失败。在startActivity的时候,系统会自动给intent加上android.intent.category.DEFAULT
,所以在AndroidManifest文件中,必须要加才行,不然没法匹配。如果你的intent设置了多个category,那么设置的必须要全部能够被匹配上才行!!!
-
data
<data android:scheme="http" android:host="www.baidu.com" android:port="80" android:path="/search/info" android:mimeType="text/plain" ></data>
data分为两部分,URI和mineType:URI是路径,而mineType是类型
可以不指定URI,系统会默认指定为content和file,也就是说,在intent中,必须指定Data为content或file才行。
intent.setDataAndType(Uri.parse("file://abc"),"image/png");