最近想写篇关于Activity启动过程源码分析的博客,在此之前先总结下Android中Activity必须要知道的一些基础知识,以方便后面能看懂Activity的源码。

一,Activity生命周期和启动模式

activity最经典的启动模式图如下: Activity你需要知道的一切_第1张图片
它分为 onCreate--onStart--onResume--onPause--onStop--onDestory.这几个阶段,这个是个android开发者肯定都很熟悉,这里不详细说,只是说下一些注意事项: 1.onStart和onStop的区别:onStart表示应用己经可见,但只运行在后台,没到前台。onStop表示acitvity运行在后台。当用户使用透明主题,不会调用onstop. 2.onResume和onpause的区别:这两个是从activity是否位于前台来回调的,是一组。 3.当新Activity启动之前,栈顶acitivity需要先onPause新的再启动。所以不能在onpause中做耗时操作。 4.当activity异常停止时,会调用onSaveInstanceState,并把所保存的Bundle传递给onRestoreInstanceState,onRestoreInstanceState是在onStart之后被调用。过程是onSaveInstanceState先保存数据,Activity会委托Window保存数据,接着Window再委托上面的顶级容器去保存,一直往上委托直到DecorView,最后它再一一通知它的子元素来保存数据。典型的委托思想。 如果onRestoreInstanceState被调用 ,那它的onSaveInstanceState参数一定有值。 5.在资源不足情况下导致的activity被杀死也会调用onSaveInstanceState。activity有三个优先级: * 前台activity。 * 可见但非前台activity(如Dialog) * 后台activity(onstop的情况)。

二,启动模式

1.启动模式介绍: android有四种模式,分别是standard,singleTop,singleTask,singleInstance。 standard:一个任务栈可以有多个实例,每个实例可以属于不同任务栈。每新建一个activity就新建一个实例。一个实例被哪个实例创建,就存在哪个实例所在的栈中,如A启动了B,那么B就位于A的栈中。不能在appliactionContext中启动它,因为非activity的context没有任务栈,解决方法是加上FLAG_ACTIVITY_NEW_TASK标识,会新建一个任务栈。 singleTop:如果activity存在栈顶,此时activity不会被重建,它的oncreate等方法不会被重调用 。如栈中有ABC,再启动C,就不会重新创建C。 singleTask:栈内复用模式,首先判断所需要的栈是否在否存在,若存在,那么只要在栈中存在,就不新建实例,并cleanTop,如果不存在,新建实例。如果所要的栈都不存在,新建栈。 如栈中有ABCD,启动C,C指定了所需的栈且栈不存在,那么就会创建一个新栈,并把C存入,此时就存在两个栈,一个是ABC,一个是C。如栈中有ABCD,启动的C所需的栈就是ABCD所在的栈,那就会把C置于栈项,C上的所有实例出栈,此时栈就变成了ABC。那么如何指定所需任务栈。一般使用TaskAffinity来指定,下面会说明。 singleInstance:具有singleTask的所有特性。不同的是,具有此模式的acitivity只能单独位于一个栈中。如创建了A,A在一个栈中,后续再创建A就不会再创建实例了。 指定启动模式有两种设置方法: 在xml中设置:andorid:launchMode="singleTop" 在代码中设置:intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);这种方法的优点是优先级比第一种高,比如同时用两种方法设置,那以第二种为主,缺点是它不能设置singleInstance。 2.所需任务栈: TaskAffinity:标识了一个activity所需要的任务栈名称。默认为应用的包名。主要和singleTask配对使用。 任务栈分为前台和后台任务栈。后台 任务栈是指位于暂停的状态。用户可以切换将后台再次调到前台。 A启动B,则B会位于A的任务栈中。(没有TaskAffinity情况下) 比如A启动B,B的TaskAffinity与A的不同,那就会创建新任务栈并把B放入。 AB是前台栈,CD是后台栈,B启动D,则变成ABCD,启动C则变成ABC. 3.标志位: 我们经常会在代码中指定标志位,主要的标志位有以下几种: FLAG_ACTIVITY_NEW_TASK:类似singleTask FLAG_ACTIVITY_SINGLE_TOP:类似singleTop FLAG_ACTIVITY_CLEAN_TOP:清当前activity栈中它本身以上的activity FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS:具有这个标记的activity不会出现在历史activity列表中。只需设置 android:excludeFromRecents="true"

三,IntentFilter匹配规则

启动activity有显式和隐式两种,如果是隐式,就要满足 IntentFilter匹配规则。 intent 有action,category,data.三个属性。只有一个intent同时匹配了action,category和data才算完全匹配。有多个filter只要有一个匹配就可以。 action只要有一个匹配就可以。 category:如果intent有这个属性,那它所有的category都必须匹配上。可以没有。没有默认有DEFAULT这个属性。为了我们的activity能接受隐式调用,就必须加上android.intent.category.DEFAULT这个属性。 data:与action类似。它为分为两部分。mimeType,URL.mineType指媒体类型,如image/jpeg等,URL如下 http://www.baidu.com:80/search/info URL默认是content和file,在不指定data 情况下就是匹配它。调用的方法如下 intent.setDataAndType(Uri.parse("file://abc"),"image/png") 完整的代码如下: Intent intent = new Intent("com.lxj.a"); intent.addCategory("com.lxj.b"); intent.setDataAndType(Uri.parse("file://abc"),"image/png") startActivity(intent); 匹配的是如下的activity <activity …………> <intent-filter> <action android:name="com.lxj.a"/> <actegory android:name="com.lxj.b"/> <actegory android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> <data android:mimeType="image/*"/> </intent-filter> <activity/> 就先写这么多吧,下一篇我会介绍下我对activity启动源码的理解。

更多相关文章

  1. android 混淆配置 实例实战项目讲解
  2. Android 只开启一个Activity实例
  3. OpenCV android sdk配置OpenCV android NDK开发实例
  4. AIDL实例分析和讲解
  5. Android常用实例—Alert Dialog的使用
  6. Android判断App前台运行还是后台运行(运行状态)
  7. Android的Activity加载方式实例分析
  8. Android中Json应用实例介绍

随机推荐

  1. Android 复习笔记之图解BroadcastReceive
  2. android aidl进程间通信
  3. android 获取应用程序占用的内存大小
  4. Android 杂记
  5. Java建造者模式,Android建造者模式的Alert
  6. Android中的ClassLoader与dex文件加密实
  7. Android高手进阶教程(十七)之---Android
  8. android 跳转到应用通知设置界面
  9. Android(安卓)处理空列表的方法(必看篇)
  10. Android(安卓)无需申请key直接调用微信/Q