**

原创,转载请在文章首部标明本地址

**

Avtivity 知识点,不断更新中

一、Activity是什么 ?

二、Activity 生命周期

三、Activity 启动方式(android:launchMode)


  1. standard 标准模式

系统默认模式,每次启动ACtivity,不管该Activity的实例是否存在,都会创建一个新的实例。该Activity与启动它的Activity属于同一个任务栈

注意:applicationContext不可启动standard模式的Activity。因为非Activity的context类型没有任务栈,那么如果要启动该模式的Activity,那该Activity无法进入任务栈,那么该Activity就不属于任何任务栈。

  • singleTop

    栈顶复用模式。如果将要启动的Activity**处于任务栈的顶部,那么该Activity会直接复用栈顶的实例。因为该Activity的实例已经存在,那么便不会执行onCreate和onStart,但会调用**onNewIntent方法。在onNewIntent中可以取出这次请求的信息。但是如果该Activity不在任务栈的顶部,则会新建该Activity的实例。

  • singleTask

    栈内复用模式。如果即将启动的Activity在某个任务栈中存在,则直接复用该Activity实例。再次过程中,只会执行onNewIntnent。具体而言,当存在该Activity所需要的任务栈,那么在该任务栈中查找该Activity的实例,如果查找到则直接复用,否则新建该Activity的实例并入栈。如果不存在该Activity的任务栈,则新建一个任务栈,然后新建Activity实例,并入栈。

    注意:当栈内复用时,那么将会把栈内该Activity之上的所有实例出栈。

  • singleInstance

    单例模式。如果某个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字段说明

    1. Android:allowTaskReparenting

      该属性用来标记当Activity退居后台之后,是否能从启动它的Activity所在的任务栈移动到与它有相同taskAffinity的任务栈。eg:在应用中页面A启动了浏览器,那么此时打开的浏览器页面B与A是属于同一个任务栈的,当B退居后台之后,B就会移动到浏览器所在的任务栈中,并且处于该栈的顶部,所以当再次打开浏览器的时候,显示的是页面B。

    2. android:allowRetainTaskState

      该属性用来标记是否能够保持原有的状态,但是该属性仅仅只对根Activity起作用(所谓根Activity一般指app的主页面)。

    3. android:clearTaskOnLaunch
      如果该属性为true,那么当启动该Activity时,便会清除该Activity所在任务栈的其他所有Activity。
    4. android:finishOnTaskLaunch
      如果设置该属性为true,那么点击home键回到屏幕之后,再次点击应用图标进入引用之后,系统自动销毁该Activity。
    5. android:alwaysRetainTaskState
      如果当前任务栈的根Activity的该属性设置为true,在该任务栈stop之后仍然保持该任务栈中所有Activity的状态。

    四、启动系统Activity

    1. 启动浏览器:

    五、数据交互

    六、系统配置变化导致的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的生命周期的管理。

    八、关于AndroidManifest所需要知道的一切

    更多相关文章

    1. Android(安卓)Widget实例日期和计时器
    2. Android中Application分析
    3. android入门开发实例
    4. android jni示范 修改无法启动注意点 jni无效
    5. activity 基础补习
    6. android中WebView和javascript实现数据交互实例
    7. android AndroidManifest.xml中android:configChanges的简介
    8. Android(安卓)launchMode
    9. Android中的Service组件详解

    随机推荐

    1. Android中View的绘制过程 onMeasure方法
    2. 【Android 初学者】开发工具介绍:studio
    3. 基于android的远程视频监控系统
    4. Android API Guides---USB Host and Acce
    5. android下载手动下载Android SDK
    6. 【Android 界面效果29】研究一下Android
    7. android 一个SQLite数据库多个数据表的基
    8. Android中的Searchview以及SearchableDic
    9. windows 8环境—android studio初步体验(
    10. 谷歌将大改Android用户体验 欲取消自定义