**
原创,转载请在文章首部标明本地址
**
Avtivity 知识点,不断更新中
一、Activity是什么 ?
二、Activity 生命周期
三、Activity 启动方式(android:launchMode)
- standard 标准模式
系统默认模式,每次启动ACtivity,不管该Activity的实例是否存在,都会创建一个新的实例。该Activity与启动它的Activity属于同一个任务栈。
注意:applicationContext不可启动standard模式的Activity。因为非Activity的context类型没有任务栈,那么如果要启动该模式的Activity,那该Activity无法进入任务栈,那么该Activity就不属于任何任务栈。
栈顶复用模式。如果将要启动的Activity**处于任务栈的顶部,那么该Activity会直接复用栈顶的实例。因为该Activity的实例已经存在,那么便不会执行onCreate和onStart,但会调用**onNewIntent方法。在onNewIntent中可以取出这次请求的信息。但是如果该Activity不在任务栈的顶部,则会新建该Activity的实例。
栈内复用模式。如果即将启动的Activity在某个任务栈中存在,则直接复用该Activity实例。再次过程中,只会执行onNewIntnent。具体而言,当存在该Activity所需要的任务栈,那么在该任务栈中查找该Activity的实例,如果查找到则直接复用,否则新建该Activity的实例并入栈。如果不存在该Activity的任务栈,则新建一个任务栈,然后新建Activity实例,并入栈。
注意:当栈内复用时,那么将会把栈内该Activity之上的所有实例出栈。
单例模式。如果某个Activity为该模式,那么该Activity只能单独的存在于某一个任务栈中,其他特征与singleTask相同。
注意: 上述任务栈是由taskAffinity属性来判定的,默认情况下所有的Activity的taskAffinity属性都是应用包名。如果想指定某个Activity所在的任务栈,修改该属性即可。该属性仅仅在于singleTask或allowTaskReparenting配合使用时才有意义。
附:FLAF vs android:launchMode
FLAG_ACTIVITY_NEW_TASK:singleTask
FLAG_ACTIVITY_CLEAR_TOP: 如果该Activity在当前任务栈中存在实体,那么销毁栈中在其之上的Activity实例,然后创建一个新的实例添加到栈顶。
FLAG_ACTIVITY_SINGLE_TOP: singleTop
总结:使用FLAG则不支持singleInstance,使用android:launchMode则不支持CLEAR_TOP
四、task字段说明
- Android:allowTaskReparenting
该属性用来标记当Activity退居后台之后,是否能从启动它的Activity所在的任务栈移动到与它有相同taskAffinity的任务栈。eg:在应用中页面A启动了浏览器,那么此时打开的浏览器页面B与A是属于同一个任务栈的,当B退居后台之后,B就会移动到浏览器所在的任务栈中,并且处于该栈的顶部,所以当再次打开浏览器的时候,显示的是页面B。
- android:allowRetainTaskState
该属性用来标记是否能够保持原有的状态,但是该属性仅仅只对根Activity起作用(所谓根Activity一般指app的主页面)。
- android:clearTaskOnLaunch
如果该属性为true,那么当启动该Activity时,便会清除该Activity所在任务栈的其他所有Activity。
- android:finishOnTaskLaunch
如果设置该属性为true,那么点击home键回到屏幕之后,再次点击应用图标进入引用之后,系统自动销毁该Activity。
- android:alwaysRetainTaskState
如果当前任务栈的根Activity的该属性设置为true,在该任务栈stop之后仍然保持该任务栈中所有Activity的状态。
四、启动系统Activity
- 启动浏览器:
五、数据交互
六、系统配置变化导致的Activity变化
1. Device Configurations
Orientation, Keyboard, Language.
2. 原理简介及解决方案
一般情况下,当Device Configuration 在Application运行时发生变化,那么系统会自动重启该Activity(此时先onSaveInstance保存数据,然后执行onDestroy,最后执行onCreate)。
所以我们必须在Activity销毁之前使用onSaveInsance保存数据,在onCreate或者onRestoreInsanceState中回复数据,以此来提供良好的用户体验。但是有时,我们需要保存大量的数据,遇到这种情况一般有两种解决方案:
a. 引用对象
由于在回调onSaveInstanceState保存的数据不适合保存大批量的数据对象(例如bitmap),而且保存的数据对象必须是Serialized的。这种情况下,当系统配置发送变化时,我们通过引用Fragment来保存数据,在fragment中保存数据对象。具体实现如下:
//注意:当保存数据时,千万不要保存任何引用Activity实例的对象,否则会造成内存泄漏
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;
}
}
然后使用FragmentManager将fragment添加到Activity中。
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());
}
}
>
b. 自己处理系统配置变化引起的改变
当系统配置发生变化时,如果Activity不需要更新数据或自动应用资源,那么可以声明自己处理该配置变化。
首先,在AndroidManifest中作如下声明:
<activity android:name=".MyActivity"
<-- 在此处定义自己要处理的变化-->
android:configChanges="orientation|keyboardHidden"
android:label="@string/app_name">
当在xml中声明的任意配置发生变化时,系统不会自动重启该Activity,此时系统将回调onConfigurationChanged()。
注意: 当App的targetSdkVersion大于等于13,如果您想处理屏幕方向切换配置变化,那么你必须在android:configuration中包含screenSize属性。
七、启动过程
1. 相关类:
Instrumentation, ActivityThread, ActivityManagerService。
2. 过程分析:
当用户启动Activity时,Instrumentation会接收该请求,然后instrumentation利用Binder向ActivityManagerService发请求。ActivityManagerService内部维护者Activity的调用堆栈(ActivityStack)及各个Activity的状态同步,ActivityManagerService通过ActivityThread去管理Activity的状态从而完成Activity的生命周期的管理。