最近在看一本书《Android开发艺术探索》,所以做一下自己的读书笔记
第一章 Activity
关于Activity,我们需要掌握的基本知识,分为以下几点:
1、Activity的生命周期
2、Activity的启动模式
3、Activity的优先级
4、Activity的匹配规则
首先,Activity的生命周期:
分类,Activity的生命周期分为正常情况下的生命周期和异常情况下的生命周期。
正常情况下的生命周期:按顺序执行为,onCreate()、onRestart()、onStart()、onResume()、onPause()、onStop()、onDestroy()。
下面是测试代码
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("TAG", "onCreate()-------->");
}
@Override
protected void onRestart() {
super.onRestart();
Log.d("TAG", "onRestart()-------->");
}
@Override
protected void onStart() {
super.onStart();
Log.d("TAG", "onStart()-------->");
}
@Override
protected void onResume() {
super.onResume();
Log.d("TAG", "onResume()-------->");
}
@Override
protected void onPause() {
super.onPause();
Log.d("TAG", "onPause()-------->");
}
@Override
protected void onStop() {
super.onStop();
Log.d("TAG", "onStop()-------->");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("TAG", "onDestroy()-------->");
}
按下返回键后的实现结果:
D/TAG: onCreate()-------->
D/TAG: onStart()-------->
D/TAG: onResume()-------->
D/TAG: onPause()-------->
D/TAG: onStop()-------->
D/TAG: onDestroy()-------->
含义,
onCreate():表示Activity正在被创建。
onRestart():表示Activity重新被启动:比如,从Activity A跳到B,按返回键,那么A会执行onRestart()、或者启动A后按下Home键,再重新进入A中,A也会调用onRestart()。
onStart():表示Activity正在启动。
onResume():表示Activity已经聚焦,也就是可见了。
onPause():表示Activity正在停止。
onStop():表示Activity即将停止。
onDestroy():表示Activity即将被销毁。
异常情况下的生命周期:多了两个回调方法,onSaveInstanceState()和onRestoreInstanceState()。前者在onStop()之前执行,后者在onStart()之后执行。产生回调的情况一般有两种:横竖屏切换(configChange)和系统的回收。
configChange,一般来说,分以下几种情况:
1,不设置该属性。切横屏时,Activity的生命周期会被执行一次,切竖屏时执行两次。
2,设置为orientation时,横竖屏都会执行一次。
3,设置为orientation|keyboardHidden|screenSize时,不会重新执行生命周期,但会回调onConfigurationChanged()方法。
区别,onStart()和onResume(),前一个表示后台可见,后一个是前台可见;onPause()和onStop(),前一个表示前台不可见,后一个表示后台不可见;onStart()和onStop()从是否可见的角度来分析,而onResume()和onPause()则是从是否位于前台的角度来分析的。
注意事项,再Activity的生命周期中,我们需要注意的是,在onPause()回调方法中,我们可以进行数据的保存,但不能进行耗时操作,因为在只有Activity A执行onPause()后Activity B才能执行onResume()。这主要是和和Activity的创建过程有关。
Activity的创建过程:
Activity的启动请求会交给Instrumentation进行处理,通过Binder发送请求给AMS(ActivityManagerService),AMS则通过ActivityThread来管理ActivityStack中的Activity。在ActivityStack中有一个方法(resumeTopActivityInnerLocked())说明了只有当前一个Activity进行onPause()后,后面一个Activity才能进行onResume()。
// We need to start pausing the current activity so the top one
// can be resumed...
boolean dontWaitForPause = (next.info.flags&ActivityInfo.FLAG_RESUME_WHILE_PAUSING) != 0;
boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving, true, dontWaitForPause);
if (mResumedActivity != null) {
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: Pausing " + mResumedActivity);
pausing |= startPausingLocked(userLeaving, false, true, dontWaitForPause);
}
if (pausing) {
if (DEBUG_SWITCH || DEBUG_STATES) Slog.v(TAG,
"resumeTopActivityLocked: Skip resume: need to start pausing");
// At this point we want to put the upcoming activity's process
// at the top of the LRU list, since we know we will be needing it
// very soon and it would be a waste to let it get killed if it
// happens to be sitting towards the end.
if (next.app != null && next.app.thread != null) {
mService.updateLruProcessLocked(next.app, true, null);
}
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
return true;
}
Activity的启动模式:standard、singleTop、singleTask、singleInstance
1. standard,标准模式。每次开启都重新创建Activity
2. singleTop,栈顶复用模式。如果当前任务站栈,栈顶是我们需要启动的Activity时,则复用,并回调onNewIntent()方法,不是就重新创建
3 .singleTask,栈内复用模式。只要当前任务栈内存在需要启动的Activity则清空该Activity之上所有Activity,复用这个Activity,并回调onNewIntent()方法,没有则重新创建
4. singleInstance,单例模式。系统会新建一个任务栈,然后把我们启动的Activity放到这个任务栈中,属于严格意义上的singleTask,自带clearTop效果
对于LaunchMode的设置,既可以在xml中,也可以在代码中设置,但后者的优先级高于前者,两者同时存在则以后者为准。但在代码中无法设置singleInstance模式,在xml中则无法设置clearTop标识,即FLAG_ACTIVITY_CLEAR_TOP。
Activity的优先级:
从高到低,依次为:前台Activity(正在和用户交互的Activity)---> 非前台可见的Activity(点击弹出dialog时)---> 后台Activity(执行onStop不可见时)
Activity 的匹配规则:
Activity的启动分为显式启动和隐式启动,一般来说启动时二者不应该共存,但如果共存的话以显式启动为主。我们在清单文件中声明四大主键时有一个标签
action的匹配:action匹配时字符串值需要完全一样,并且区分大小写。当存在多组时,只要一组匹配就可以匹配上。隐式启动时,action是必须存在的,并可以通过Intent的resolveActivity方法进行判断,如果找不到匹配的Activity就会返回null。
category的匹配:category可有可无,如果有的话,那么所有的category都必须和过滤规则中的一个category相同。没有的话也没关系,因为系统会默认的给我们加上DEFAULT这个值。
data的匹配:由两部分组成,mimeType和URI。mimeType是指媒体类型;URI的结构则为:Scheme://host/port/path。