Intent在Android开发中的使用总结

关于Intent的使用,其实已经有很多文章进行了详细的介绍,包括谷歌开发者网站也有进行很详细的介绍。这里再重复这个轮子的过程,主要是加深自己对Intent的认识,以及方便之后的查阅。

1、Intent是什么

Intent是一个消息传递对象,可以使用它来完成对其它应用组件的请求操作。从这里可以看出,Intent是一个对象,它的主要功能有两个一个是传递消息,另外一个就是请求应用组件了,而这个传递消息也就是向请求的应用组件来传递的消息。

Inent请求的应用组件主要有三类

*请求Activity

通过将 Intent 传递给 startActivity(),可以启动新的 Activity 实例。Intent 描述了要启动的 Activity,并携带了任何必要的数据。

*请求Service

通过将 Intent 传递给 startService(),可以启动服务执行一次性操作(例如,下载文件)。Intent 描述了要启动的服务,并携带了任何必要的数据。

*请求Broadcast

通过将 Intent 传递给 sendBroadcast()、sendOrderedBroadcast() 或 sendStickyBroadcast(),可以将广播传递给本应用或者其他应用。

2、Intent的分类

Intent在实际使用过程总可以根据其请求组件的方式来分成隐式Intent以及显示Intent

2.1、显示Intent

当在使用Intent请求组件时,按名称(完全限定类名)指定要启动的组件,我们吧这种Intent叫做显示Intent,显示Intent的使用范围很广,平时在Activity页面跳转时就基本都是使用的显示Intent,如下所示

Intent intent = new Intent(this,TestActivity.class);
startActivity(intent);

这种使用方式使用的Intent,就是显示Intent,显示Intent传递数据常常通过intent.putExtra()的方式来进行

intent.putExtra("key","value");

2.2、隐式Intent

当在使用Intent请求组件时,与隐式Intent相反,显示Intent不会指定特定的组件,而是声明要执行的常规操作(action),从而允许其他应用中的组件来处理它,说的比较玄乎,直接看看代码就能明白。

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);

这里的Intent.ACTION_DIAL对应字符串

public static final String ACTION_DIAL = "android.intent.action.DIAL";

而这里就可以看出隐式Intent和显示Intent的明显不同了,但是有童鞋可能会疑惑了,根据这个Intent.ACTION_DIAL,怎么调用起了系统的拨号界面了呢,这个就要细说隐式Intent了,这个放在下一节详细介绍。

3、细说隐式Intent的使用

隐式Intent为何根据字符串可以调用起来一个页面呢,聪明的童鞋肯定能够想那是因为页面和字符串存在一个对应关系,这就关系就是在被调动页面的AndroidManifest.xml文件中进行定义了。

例如,这里应用2中AndroidManifest.xml配置文件中对TargetActivity页面进行如下配置

<activity android:name=".TargetActivity">
    <intent-filter>
        <action android:name="com.yoryky.intent.action.TARGET"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

之类看到对activity注册添加了一个intent-filter 的标签,这个标签就是关键了,看名字也能大概知道这个标签是用来过滤Intent启动的组件的(这里是Activity),这里TargetActivity和action对应的name就形成了一个对应关系(并不一定是一一对应关系),我们便能够其他应用中通过

Intent intent = new Intent("com.yoryky.intent.action.TARGET");
start(intent);

这种方式来启动TargetActivity,当还有其它模块的Activity也通过com.yoryky.intent.action.TARGET这个字符串来进行过滤的话,那么以上intent请求的Activity组件便有多个,系统就会弹出提示框来让用户指定启动的具体使哪一个Activity组件。

到这里可能有同学会问了,以上intent-filter 标签中除了action过滤外,不是还有个category
这个category标签是用来声明对应组件的类别的,Intent 过滤器既可以不声明任何 category 元素,也可以声明多个此类元素,当声明了一个或者多个category 元素时,用来启动该组件的Intent必须满足category的过滤条件,才能启动对应的组件。

实际上intent-filter 中除了可以添加action 以及category 这两个标签外,还可以添加data 标签进行过滤。

在目标data标签中包含了以下几种子元素,它们定义了Uri的匹配规则:

android:scheme 匹配Uri中的前缀,除了“http”、“https”、“tel”…之外,我们可以定义自己的前缀

android:host 匹配Uri中的主机名部分,如“google.com”,如果定义为“*”则表示任意主机名

android:port 匹配Uri中的端口

android:path 匹配Uri中的路径

android:mimeType 匹配Uri路径所指数据的MIME类型

例如这里再AndroidManifest.xml中对TargetActivity作如下配置

<activity android:name=".TargetActivity">
    <intent-filter>
        <action android:name="com.yoryky.intent.action.TARGET" />
        <category android:name="android.intent.category.DEFAULT" />
        <data
            android:host="com.yoryky.example.data"
            android:path="/target"
            android:port="1122"
            android:scheme="test"
            android:minmeType="text/xml"/>
    </intent-filter>
</activity>

这里看到加入了data 标签进行过滤,那么在其它模块中通过隐式Intent来请求这个TargetAcivity时,就必须严格按照data 标签的过滤条件来启动TargetActivity

Intent intent = new Intent("com.yoryky.intent.action.TARGET");  
intent.setDataAndType(Uri.parse("test://com.yoryky.example.data:1122/target"),"text/xml"); 
startActivity(intent);  

当然data 标签不是必须的,data 标签所包含的素数也不需要每种都使用来过滤,这样过滤的条件也就会宽松一些。

需要注意的是,也是从 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI。具体表现为,当我们在应用中使用包含 file:// URI 的 Intent 离开自己的应用时,程序会发生故障。

开发中,如果我们在使用 file:// URI 时忽视了这两条规定,将导致用户在 7.0 及更高版本系统的设备中使用到相关功能时,出现 FileUriExposedException 异常,导致应用出现崩溃闪退问题,而这两个过程的替代解决方案便是使用 FileProvider,关于这方面的知识可以参考关于 Android 7.0 适配中 FileProvider 部分的总结 这篇文章。

到这里我想总结的Intent知识就差不多了,有什么问题还望各位童鞋多多指教。

参考文献

1、Android总结篇——Intent机制详解及示例总结

2、关于 Android 7.0 适配中 FileProvider 部分的总结

3、Intent属性详解三 data、type和extra

4、Intent 和 Intent 过滤器

5、Intent

6、URI

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值