你应该知道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



作者:bogerLiu
链接:https://www.jianshu.com/p/732ea3304ffc
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。 优质内容筛选与推荐>>
1、JAVA-类加载机制(4)-其他
2、java中Collection和collections的区别
3、(一)大数据-Hadoop2.7.3伪分布搭建
4、UVA - 1225 Digit Counting
5、scapy安装及SCTP包分析


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn