Intent浅析

这篇文章主要内容有一下几方面:

  1. Intent的简要;
  2. Intent的分类;
  3. Intent字段;
  4. Intent的隐式匹配规则;

Intent的简要

Intent是一个消息传递的对象,是组件之间沟通的重要载体。Intent主要有这几个用法。

 

  1. 启动Activity。通过调用startActivity方法,Intent启动一个Activity。Intent可以携带数据,把当前页面的数据传递到下一个页面。通过startActivityForResult可以在目标页面关闭(setResult)时,在当前页面onActivityResult回调中得到处理。
  2. 启动Service。Service是一个没有用户界面的组件。它的生命周期方法都在主线程中。通过调用startService可以启动指定服务,并通过intent传递数据。也可以通过bindService绑定服务,保持界面和service通信。
  3. 发送广播。注册了的广播接收器将可以接收到广播。调用sendBroadcast,sendOrderdBroardcast等可以发送广播。

Intent分类

  1. 显示Intent。Intent属性中指定了ComponentName。
  2. 隐式Intent。Intent中未指定ComponeName。创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,找到要启动的相应组件。如果匹配了Intent过滤器,那么系统将会启动对应的组件,并传递intent对象。如果多个匹配成功,则会显示选择应用对话框,由用户进行选择。

问题来了,怎么设置ComponentName?如下方法都可以,他们都是一个意思。

  public @NonNull Intent setClass(@NonNull Context packageContext, @NonNull Class<?> cls) {
        mComponent = new ComponentName(packageContext, cls);
        return this;
    }
  public @NonNull Intent setClassName(@NonNull String packageName, @NonNull String className) {
        mComponent = new ComponentName(packageName, className);
        return this;
    }
   public @NonNull Intent setComponent(@Nullable ComponentName component) {
        mComponent = component;
        return this;
    }

注意:启动Service必须用显示Intent,并且不要为Service组件设置Intent过滤器。隐式的Intent启动服务有安全隐患。并且从API21以后,使用隐式的Intent进行bindService,系统将会报错。

Intent字段

  • 经典的Activity动作定义

    (简单说明几个,更多内容请见Action定义)。我们平常只需要理解,并不需要背下来,需要时查询资料即可。
  1. public static final String ACTION_MAIN = "android.intent.action.MAIN";
    作为应用的入口响应,并不接收数据。应用启动第一Activity,必须设置这个action,。
  2. public static final String ACTION_VIEW = "android.intent.action.VIEW";
      向用户展示数据。他会根据你的一些数据信息,展示对应的操作。比如,当你用tel:和URL一起使用,将会调用拨打电话;当你用mailto:和URL一起使用,将会打开邮箱。如下所示:
           Intent intent = new Intent();
           intent.setAction(Intent.ACTION_VIEW);
    //     intent.setData(Uri.parse("tel:手机号"));
           intent.setData(Uri.parse("mailto:邮箱"));
           startActivity(intent);

     

  3. public static final String ACTION_PICK = "android.intent.action.PICK";
    通过制定数据类型,来从制定数据中,选择一个数据并返回。如打开系统相册选择相片,打开文件选择文件。

全局变量
 

    private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private ArraySet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
  1. mAction
    表示的是当前Intent通过setAction方法后设置的字符串。
  2. mData 
    表示未一个Uri形式的数据。
  3. mType
    用户设置的数据类型
  4. mPackage
    默认为空,intent会寻找所有包名匹配。如果设置了包名,则只会通过指定包名下匹配。可以通过调用setPackage设置
  5. mComponent
    显示设置的跳转的目标组件。setClass等可以设置。设置之后,启动类型为显示启动,而不是隐式启动。
  6. mFlags
    mFlags可以设置很多值。每个值得作用都是不一样的。具体详细请见flag说明
  7. mCategories
    分类,也是用于匹配过滤器的字段。
  8. mExtras
    Bundle类型,用于Intent携带数据。
  9. mClipData
    根据英文翻译理解,主要用来附加额外的数据,这些数据被包含在剪切板上进行读写。

 

 

Intent匹配规则

匹配规则主要针对隐式启动组件。基本用于启动Activity。Activity在androidManifest.xml注册时,设置intent-filter标签,来进行过滤。实际上是intent-filter标签属性和Intent设置的属性进行匹配,匹配成功,则会启动对应的组件。下面开始按照对应的属性进行分析:

  1. Action
    Intent中通过setAction设置的属性必须和Intent-filter中的某个<action>标签匹配。只需要匹配上其中一个,该action匹配成功。如果过滤器没有<action>标签,则该组件无法被匹配。
  2. Category
    Intent可以addCategory来添加多个category,过滤器中也可以声明多个(可以不设置)<category>标签。如果Intent中设置每个category都能在过滤器中找到,则匹配成功。如果Intent没有设置category,则每次都会匹配成功。(匹配成功只是当前属性匹配成功,所有匹配成功才算隐式启动成功)。
  3. type
    Intent可以调用setType设置Type,Intent-filter的<data>标签可以设置type属性。匹配规则和data一起分析。
  4. data(uri)
    <data android:scheme="string"
          android:host="string"
          android:port="80"
          android:path="/string"
          android:pathPattern="string"
          android:pathPrefix="/string"
          android:mimeType="text/plain"/>
    

    这个data不是指标签<data>,而是标签内的android:scheme。形式 <scheme>://<host>:<port>/<path>。
    a. 如果未指定scheme,则会忽略host后面的
    b. 如果未指定host,则会忽略port后面的
    c. 如果未指定scheme host port,则会忽略后面的path
    忽略之后,然后开始进行匹配data。
    a. 如果过滤器没有设置URI和MIME,那么没有设置URI和MIME的intent才能匹配成功。
    b. 如果过滤器只设置了URI ,那么只有URI匹配成功并且没有设置MIME的Intent,才能匹配成功。
    c. 如果过过滤器只有MIME,只有不含URI但包含MIME的intent才能匹配成功。
    d. 仅当 MIME 类型与过滤器中列出的类型匹配时,同时包含 URI 类型和 MIME 类型(通过显式声明,或可以通过 URI 推断得出)的 Intent 才会通过测试的 MIME 类型部分。 如果 Intent 的 URI 与过滤器中的 URI 匹配,或者如果 Intent 具有 Content:或 file: URI 且过滤器未指定 URI,则 Intent 会成功匹配URI。

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值