你应该知道Activity一切

activity启动模式

1.SingleTop 栈顶复用,当Activity位于栈顶的时候在启动该Activity,那么这个Activity不会被重新创建,会调用onNewIntent(Intent intent),如果不在栈顶,则跟默认的启动模式一样,会重新创建。
2.SingleTask 栈内复用,当Activity已经创建过,且存在栈内了,当再启动该Activity,那么会把该Activity上面所有Activity都退出栈,并调用onNewIntent(Intent intent)方法
3.SingleInstance 新的任务栈,当以这种模式启动,会创建一个新的ActivityTask存放这个Activity
4.Standard 默认模式,你只要启动 我就给你创建,并压入栈内。

虽然SingleTask,SingleTop都可能会复用Activity,但是注意的是SingleTop是栈顶复用。

activity的flag

以下摘自intent源码

  • FLAG_ACTIVITY_NO_HISTORY

/**
* If set, the new activity is not kept in the history stack. As soon as
* the user navigates away from it, the activity is finished. This may also
* be set with the {@link android.R.styleable#AndroidManifestActivity_noHistory
* noHistory} attribute.
*
* <p>If set, {@link android.app.Activity#onActivityResult onActivityResult()}
* is never invoked when the current activity starts a new activity which
* sets a result and finishes.
*/
当标记该FLAG后启动的activity是不会在存在ActivityTask ,例如A启动B,B启动C,C finish()后看到的界面是A,这个时候B也同时被 finish()了

  • FLAG_ACTIVITY_SINGLE_TOP

singleTop设置后形势与启动模式SingleTop一致

  • FLAG_ACTIVITY_NEW_TASK

标志启动在一个新的Task中。当与FLAG_ACTIVITY_CLEAR_TOP一起用,与启动模式SingleTask一致FLAG_ACTIVITY_MULTIPLE_TASK, 消除FLAG_ACTIVITY_NEW_TASK这个标志位的FLAG_ACTIVITY_CLEAR_TOP,清除这个activity栈顶的所有activity

  • FLAG_ACTIVITY_FORWARD_RESULT

/**
* If set and this intent is being used to launch a new activity from an
* existing one, then the reply target of the existing activity will be
* transfered to the new activity. This way the new activity can call
* {@link android.app.Activity#setResult} and have that result sent back to
* the reply target of the original activity.
*/
这个标志位用于A启动B,B启动C,C要把result返回给A,这个时候B启动C的时候带上这个标志位就可以了。这个时候C finish()的时候必须带上 setResult 方法,否则系统会抛出异常。

  • FLAG_ACTIVITY_PREVIOUS_IS_TOP

即 A---> B --->C,若B启动C时用了这个标志位,那在启动时B并不会被当作栈顶的Activity,而是用A做栈顶来启动C。
此过程中B充当一个跳转页面。典型的场景是在应用选择页面,
如果在文本中点击一个网址要跳转到浏览器,而系统中又装了不止一个浏览器应用,
此时会弹出应用选择页面。在应用选择页面选择某一款浏览器启动时,就会用到这个Flag。
然后应用选择页面将自己finish,以保证从浏览器返回时不会在回到选择页面。
经常与FLAG_ACTIVITY_FORWARD_RESULT 一起使用。

  • FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS,
  • FLAG_ACTIVITY_BROUGHT_TO_FRONT,
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED,
  • FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY,
  • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,
  • FLAG_ACTIVITY_NEW_DOCUMENT,
  • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET,

以上这些要么是系统用的,要么是不常用,不做解释了

  • FLAG_ACTIVITY_NO_USER_ACTION,

禁止activity调用onUserLeaveHint()。onUserLeaveHint()作为activity周期的一部分,它在activity因为用户要跳转到别的activity而退到background时使用。比如,在用户按下Home键(用户的操作),它将被调用。比如有电话进来(不属于用户的操作),它就不会被调用。注意:通过调用finish()时该activity销毁时不会调用该函数。

  • FLAG_ACTIVITY_REORDER_TO_FRONT,

/**
* If set in an Intent passed to {@link Context#startActivity Context.startActivity()},
* this flag will cause the launched activity to be brought to the front of its
* task's history stack if it is already running.
*
* <p>For example, consider a task consisting of four activities: A, B, C, D.
* If D calls startActivity() with an Intent that resolves to the component
* of activity B, then B will be brought to the front of the history stack,
* with this resulting order: A, C, D, B.
*
* This flag will be ignored if {@link #FLAG_ACTIVITY_CLEAR_TOP} is also
* specified.
*/
注释说的很清楚 就是把要启动的放到最栈顶 但是与FLAG_ACTIVITY_CLEAR_TOP相冲突

  • FLAG_ACTIVITY_NO_ANIMATION

启动不带动画

  • FLAG_ACTIVITY_CLEAR_TASK

全部清空栈

  • FLAG_ACTIVITY_TASK_ON_HOME

该flag启动的activity,点击返回键会回到launcher.需要与FLAG_ACTIVITY_NEW_TASK一起使用,并且FLAG_ACTIVITY_NEW_TASK模式生效(参考该属性)后,该flag才会起作用. FLAG_ACTIVITY_RETAIN_IN_RECENTS,与activity设置autoRemoveFromRecents = false属性效果一样.是指当前activity销毁后,是否还在概览屏幕中显示.(5.0之后生效)

  • 说明

以上参考Intent源码注释,《Android开发艺术探索》以及 这篇文章

IntentFilter匹配规则

启动Activity有隐式和显式2中方式,这里首先简单说一下显式启动

显式启动Activity

Intent intent = new Intent();
intent.setClass(@NonNull Context packageContext, @NonNull Class<?> cls)
context.startActivity(intent);

这里是简单的调用intent启动activity,一般是不会出错,但是如果启动系统的activity,容易启动失败,这个时候 就需要intent.resolveActivity()来确定这个activity是否能够安全启动,当不反回为null的时候就可以安全启动。

resolveActivity 的源码如下
核心方法就是这个
   ResolveInfo info = pm.resolveActivity(
            this, PackageManager.MATCH_DEFAULT_ONLY);

会去遍历满足条件的activity的返回回来,

PackageManager.MATCH_DEFAULT_ONLY这个的作用就是只返回Action和Category满足的activity。

隐式启动Activity

隐式启动需要在activity的标签内设置Intent-filter来过滤对应的activity。

微信图片_20180627112322.png

如图所示的intent-filter,这里按照字母顺序说明一下

  • Action

action 决定跳转的方向,也是自己可以制定的筛选规则,就如我们常用的intent.getAction().equal("test")来决定我们的intent是否合适

action的匹配规则

简言之如果intent-filter中有多个action,那么只要隐式启动的intent中有一个能够对应上那么就能够匹配成功

  • Category

category这个是用系统的。默认的隐式启动的activity的intent-filter都要注明一个default这个category。

Category匹配规则

如果intent-filter中有多个category那么intent就必须要与每一个category都要相对应,换句话说就是 filter中有3个 那么intent中也必须有3个而且是一模一样的。但是默认的android.intent.category.DEFAULT在startActivity时是不用添加的,在启动的时候 默认Android系统会在intent上自动设置这个category

  • Data

data就是常用的scheme匹配规则,data中常用的就是网页启动app
摘自《Android开发艺术探索》

data是由2部分组成,URI 和mineType
图片里 除了mineType这个属性外 就都是URI的内容了
URI格式如下
<Scheme>://<Host>:<Port>/[<path>|<pathPattern>|<pathPrefix>]

栗子
http://www.baidu.com:80/search/info

scheme: URI的模式,重中之重,如果没有scheme那么整个data就无效了。
host:URI主机名,和scheme一样,一个data至少包含scheme和host
port:端口号
path,pathPattern,pathPrefix都是指路径,path是指完整路径,pathPattern也是完整路径,但是里面可以包括通配符“” “”表示0个或多个任意字符。pathPrefix表示路径的前缀信息。

接下来就是说明mineType
<data mineType="image/"/>
这里data就必须要指明mineType为“image/
”,否则无法成功,另外就是有时候虽然data没有指明URI,但是他是有默认值的scheme是content或者是file,所以对于这里<data mineType="image/*"/>这个data的匹配规则就必须intent.setDataAndType(Uri.parse("content://test"),"image/*"));
如果intent要设置data和type就必须要用这个setDataAndType,对于setData,setType会相互抵消另一个参数,

接下来说一下activity的声明周期

先总体说明一下
oncreate->onstart->onRestoreInstance->onResume->onPause->onSaveInstance->onStop->onDestory
其中oncreate,onDestory之后是前台生命周期,onResume到onPause是可见生命周期。

具体activity启动流程如下2图(这两个图是我结合《Android开发艺术探索》和Android源码画出来的
微信图片_20180627140600.png
微信图片_20180627140007.png

这里面我备注了很多,可以看下我分享出来的图1
图2

大家也可以按照我的思路对应着图的顺序照着源码走一遍

最有有什么问题,大家可以留言,加我微信探讨
微信图片_20180627141343.jpg

End

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容