Avtivity 知识点,不断更新中

**

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

**

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所需要知道的一切

    时间: 2024-10-08 10:06:06

    Avtivity 知识点,不断更新中的相关文章

    C++知识点总结(更新中)

    1. 指针和引用的区别 本质:指针是地址,引用是别名. 对象绑定:指针可以为空,如果前面不加const修饰,可在运行过程中改变其指向的对象:引用不能为空,必须初始化,一旦与对象绑定则不可改变. 对象访问:指针是间接访问对象,引用是直接访问对象. 占用空间:指针的大小在32位机器上4个字节,64位机器上8个字节:引用的大小为其绑定对象的大小. 运算符:指针和引用的++运算符意义不同. 安全性:引用更加安全,指针使用灵活,但容易产生野指针.

    MySQL数据库知识点整理 (持续更新中)

    一.修改用户密码 格式(在命令行下输入):mysqladmin -u 用户名 -p旧密码 password 新密码 1. 给root添加密码ab12:  mysqladmin -uroot -password ab12 2. 将root的密码修改为djg345:    mysqladmin -uroot -pab12 password djg345 二.添加新用户 格式:grant 权限 on 数据库名.表名 to 用户名@登录主机  identified by "密码" 1. 增加一

    android点滴之触控相关知识点(持续更新)

    1.检查当前屏幕有多少个触摸点. 使用MotionEvent的getPointerCount()方法. 2.多点触控下,触摸的状态的检测 MotionEvent类中方法getActionMasked(),这个方法可以检查触摸的状态: 当只有一个触摸点时(只用一根手指触摸屏幕),按下是0,起来是1,移动是2: 当触摸点多于1时(多根手指触摸屏幕),按下是5,起来是6,移动是2: 3.多点触控下,每个触点的分类处理 多点触摸时 假如是第i个点 int x = event.getX(i); int y

    linux学习资料持续更新中

    一.LINUX基础教程 1.老男孩系列免费视频: 1) linux高薪入门实战视频教程(第二部)老男孩linux教程 http://edu.51cto.com/course/course_id-1035-page-1.html 2) 跟着老男孩从0开始一步步实战深入学习linux运维(三) http://edu.51cto.com/lesson/id-11909.html linux学习资料持续更新中,布布扣,bubuko.com

    Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过start方法启动线程--->线程变为可运行可执行状态,然后通过数据产生共享,线程产生互斥---->线程状态变为阻塞状态---->阻塞状态想打开的话可以调用notify方法. 这里Java5中提供了封装好的类,可以直接调用然后构造阻塞状态,以保证数据的原子性. 2.如何实现? 主要是实现Blo

    Hello World!的各种编程语言程序(持续更新中……)

    对于很多学习编程语言新手们,可能接触到的第一个程序就是"Hello World"的输出程序,笔者想在此篇简短的博文中介绍关于各种编程语言的"Hello World"输出程序. 至今,笔者仅仅接触过C++和Python两种编程语言,而且都仅仅是新手,所以此次只能写C++和Python两种语言的"Hello World"输出程序,但此篇博文会随着笔者学习的编程语言种类的增多而不断完善. 1. C++语言 #include<iostream>

    linux网络编程学习笔记之二 -----错误异常处理和各种碎碎(更新中)

    errno 在unix系统中对大部分系统调用非正常返回时,通常返回值为-1,并设置全局变量errno(errno.h),如socket(), bind(), accept(), listen().erron存放一个正整数来保存上次出错的错误值. 对线程而言,每个线程都有专用的errno变量,不必考虑同步问题. strerror converts to English (Note: use strerror_r for thread safety) perror is simplified str

    shell脚本练习题(更新中...)

    练习题(这里贴的是自己写的代码, 网上给的题目代码我会附加在最下面) 1. 编写shell脚本,计算1-100的和: 1 #!/bin/bash 2 #caculate the sum of numbers from 1 to 100 3 4 sum=0 5 for i in `seq 1 100`; do 6 sum=$[$sum+$i] 7 done 8 echo $sum 2. 编写shell脚本,要求输入一个数字,然后计算出从1到输入数字的和,要求,如果输入的数字小于1,则重新输入,直到

    ArcGIS 网络分析[1] 介绍与博文目录【更新中】

    网络分析是个热点,理论上是属于计算机图形学和数据结构的,GIS以此为基础做出应用. 以下列举本人在学习中遇到的网络分析问题与经验总结. 平台:Windows 10操作系统,ArcGIS for Desktop 10.2或更高版本 用到的软件和SDK:VisualStudio 2012或更高版本.ArcGIS Objects 10.2或更高版本.Microsoft.NET Framework 3.5或更高版本 [网络分析介绍] [博文目录] 1. ArcGIS 网络分析[2] 利用自定义基础数据创