Activity进阶-IntentFilter,Activity启动过程

IntenterFilter的匹配规则

启动Activityf分两种,显示调用和隐士调用;显示需要明确指定被启动对象的组件信息,包括包名和类名,而隐士调用则不需要明确指定组件信息;原则上一个Intent不应该既是显示调用又是饮食调用,二者共存的话以显示调用为主。

隐式调用需要Intent能匹配目标组件的IntentFilter中所设置的过滤信息,如果不匹配将无法启动目标Activity;IntentFilter中的过滤信息有action,category,data。示例:

<activity
            android:name="com.ryg.chapter_1.ThirdActivity"
            android:configChanges="screenLayout"
            android:label="@string/app_name"
            android:launchMode="singleTask"
            android:taskAffinity="com.ryg.task1" >
            <intent-filter>
                <action android:name="com.ryg.charpter_1.c" />
                <action android:name="com.ryg.charpter_1.d" />

                <category android:name="com.ryg.category.c" />
                <category android:name="com.ryg.category.d" />
                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

一个过滤表中action,categroy和data可以有多个,一个Intent同时匹配action类型,category类别,data类别才算完全匹配,只有完全匹配才能成功启动目标Activity。一个Activity中可以有多个intent-filter;一个Intent只要能匹配任何一组intent-filter即可启动对应Activity。

1.action的匹配规则

action是一个字符串;action的匹配要求intent中的action存在且必须和过滤规则中的一个action相同,可以有多个,但必须有,一个相同就可以;值得注意:区分大小写。

2.category的匹配规则

category是一个字符串,与action匹配规则不同;要求如果intent中含有category;那么多有category都必须和过滤条件其中一个category相同;如果没有category,也是可以成功的,因为有默认的category“android.intent.category.DEFAULT”;

3.data的匹配条件

与action类似;data由两部分组成mimeType和URI.mineType指媒体类型,比如image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片,文本,视频等不同媒体格式,而URI中包含的数据比较多,结构是:

<scheme>://<host>:<port>/[<path>|<pathPrefix>|<pathPattern>]

Scheme:Uri的模式,比如http、file、Content等,如果没有这个其他参数无效,所以说必须指定;默认值是file

Host:Uri的主机名,比如www.baidu.com,如果host没有指定,那么整个Uri其他参数无效

Post:Uri端口号,比如80,仅当有scheme和host参数时候port参数才有意义

剩下三个参数表示路径信息。

要求Intent中必须含有data数据并且能够完全匹配某一个data.


当隐式启动一个Activity时候,可以做判断看是否有Activity能匹配我们的隐士intent,判断方法:采用PackageManager的resolveActivity方法或者Intent的resolveActivity;如果找不到匹配的Activity就会返回null。


Activity的启动过程

首先说两句体外话,Android的四大组件中除了BroadcastReceiver以为,其他三个组件必须在AndroidManifest中注册,对广播来说可以动态注册也可以静态注册;调用方式上来说,Activity、Service、BroadcastReceiver需要借住Intent,而ContentProvider则无需借住Intent。

Activity的工作过程

概述:Activity启动请求由Instrumentation处理,它通过Bind而向AMS(ActivityManagerService)发送请求,AMS维护一个ActivityStack负责栈内Activity的状态同步,AMS通过ActivityThread同步Activity状态从而完成Activity的生命周期方法调用。

从startActivity方法开始,startActivity方法有好多中重载方式,但最终都是调用startActivityForResult方法;

其中通过Instrumentation的exexStartActivity(其中会调用checkStartActivityResult方法,作用检查启动Activity的结果,没有在配置文件中注册的话,就会在这报错)方法,真实实现是ActivityManagerNative.getDefault()的startActivity方法完成(ActivityManagerNative是继承Binder并且实现了IActivityManager这个Binder接口);具体实现在AMS(采用单例模式对外提供)中的StartActivity;AMS中维护着ActivityStack,先通过ActivityStackSupervisor的startActivityMayWait方法,进而调用startActivityLocked方法>>调用startActivityUncheckedLocked方法调用到ActivityStack的resumeTopActivitieslocked方法(从ActivitySackSupervisor转移到了ActivityStack)>>但又调用了ActivitySackSupervisor中的startSpecificActivityLocked方法>>调用realStartActivityLocked方法(又回到ActivitySackSupervisor);
其中有个重要部分app.thread,他的类型为IApplicationThread,这个Binder接口的实现者完成大量和Activity以及Service启动/停止相关功能;它的实现者:ApplicationThread(ActivityThread的内部类);那么Activity的启动最终来到ApplicationThread中,通过scheduleLaunchActivity方法启动Activity,该方法主要是发送一个请求Activity的消息交给handler(H)处理;然后又ActivityThread的handleLaunchActivity方法实现,调用performLaunchActivity最终完成Activity对象的创建和启动过程。


performLaunchActivity方法主要完成几个事情:

1.从ActivityClientRecord中获取待启动的Activity的组件信息

2.通过Instrumentation的newActivity方法使用类加载器创建Activity对象

3.通过LoadedApk的makeApplication方法来尝试创建Application对象(注意没有创建,有了不创建,一个应有只有一个)

4.创建Contextimpl对象并通过Activity的attach方法完成一些重要数据的初始化

5.调用Activity的onCreate方法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值