问题1:onStart和onStop、onResume和onPause分别是对应的一对,但是看起来差不多,有什么不同呢?
答:
区别是onStart和onStop是从Activity是否可见这个角度来回调的,而onResume和onPause是从Activity是否位于前台这个角度来回调的。
问题2:假设当前Activity为A,如果这时用户打开一个新ActivityB,那么B的onResume和A的onPause哪个先执行呢?
答:
从源码简单理解,启动Activity的请求会由Instrumentation来处理,然后它通过Binder向AMS发请求,AMS内部维护着一个ActivityStack并负栈内的Activity的状态同步,AMS通过ActivityThread去同步Activity的状态从而完成生命周期方法的调用。从源码上看是旧的Activity先onPause,然后新的Activity再启动。因为必须onPause执行完成以后新Activity才能Resume,应当尽量避免在onPause中做耗时操作,如果是跳转的话,尽量在onStop中做操作,从而使得新Activity尽快显示出来并切换到前台。
问题3:异常情况下生命周期是怎么样的?
答:
android:configChanges=“orientation”),Activity会被销毁,其onPause、onStop、onDestroy均会被调用,同时由于Activity是在异常情况下终止的,系统会调用onSaveInstanceState来保存当前Activity的状态。这个方法在onStop之前调用,但是跟onPause没有既定的时序关系,可能在onPause之前调用,也有可能在之后调用。当Activity被重新创建后,系统会调用onRestoreInstanceState,并且把Activity销毁时onSaveInstanceState方法所保存的Bundle对象作为参数同时传递给onRestoreInstanceState和onCreate方法。因此可以通过onRestoreInstanceState和onCreate方法来判断Activity是否被重建了。onRestoreInstanceState的调用时机在onStart之后。数据保存和恢复的过程是:Activity被意外终止时,Activity会调用onSaveInstanceState去保存数据,然后Activity会委托Window去保存数据,接着Window再委托它上面的顶级容器去保存数据。顶层容器是一个ViewGroup,一般来说它也可能是DecorView。最后顶层容器再去一一通知它的子元素来保存数据,这样整个数据保存过程就完成了。View的绘制过程、事件分发等都是采用类似的思想,至于子元素具体保存哪些数据,可以直接查看子元素实现的onSaveInstanceState方法,如TextView等。
问题4:Activity的4种启动方式的区别?
答:4种启动模式分别为:
standart:标准模式,是系统的默认模式。每次启动一个Activity都会重新创建一个新的实例,不管这个实例是否已经存在。需要注意的是如果用ApplicationContext去启动standard模式的Activity会报错,原因是standart模式的Activity默认为进入启动它的Activity所属的任务栈中,而ApplicationContext是应用的context,没有所谓的独立任务栈,因此会报错。可以在启动时加上FLAG_ACTIVITY_NEW_TASK标记位用来创建新的任务栈解决。
singleTop:栈顶复用模式。如果要打开的Activity已经位于任务栈的栈顶,则复用,而且会回调onNewIntent方法。
singleTask:栈内复用模式。这是一种单实例模式,如果要打开的Activity在栈中存在,则会复用。并且把位于它上面的Activity清空,同样会回调onNewIntent方法。
singleInstance:单实例独栈模式。除了有singleTask模式的所有特性外,具备该属性的Activity独占一个栈。
问题5: IntentFilter匹配规则是什么样的?
答:
action匹配规则:一个过滤规则中可以有多个action,只要Intent中的action能够和过滤规则中的任何一个action完全相同即可匹配成功。
category匹配规则:category的匹配规则和action不同,它要求Intent中如果含有category,那么所有的category都必须和过滤规则中的其中一个category相同。比如Intent.addcategory(“com.mhwang”)那么Activity中的category必须要有com.mhwang的category。
data匹配规则:data由2部分组成,mimeType和URI。mimeType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等。URI可以理解为详细的内容地址,如:
content://com.mhwang.project:200//folder/test
http://www.mhwang:80/search/info
data的匹配规则跟action的类似,只要能够完全匹配规则中的某一个data就可以了。
使用隐式启动Activity的时候,可以做一下判断是否有Activity能够匹配该Intent。方法有2种:
一是采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果找不到匹配的Activity则返回null。二是使用PackageManager的queryIntentActivityes方法,这个方法和resolveActivity方法不同的是:它不是返回最佳匹配的Activity信息,而是返回所有成功匹配的Activity信息,这2个方法的原型如下图:
第二个参数一般使用MATCH_DEFAULT_ONLY这个标记位,意思是仅仅匹配那些在intent-filter中声明了这个category的Activity。使用这个标记位的意思是只要上述2个方法不返回null,那么startActivity是一定可以成功的,否则有可能失败。因为不含有Default这个category的Activity是无法接收隐式Intent的。