大家好,感谢邀请,今天来为大家分享一下深入解析Android应用间交互:Intent技术详解的问题,以及和的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
启动Activity并启动Service发送广播Intent类型
显示意图。 Intent中明确包含了要启动的组件的完整类名(包名和类名),那么这个Intent就是express的,即显式的。它适合在App内使用,因为开发人员必须知道他们开发的组件的完整类名。隐式Intent,Intent中不包含要启动的组件的完整类名,那么该Intent是implicit的,即隐式的。用法:隐式Intent只有当我们想通过自己App中的Intent来启动另一个App的组件,以便另一个App的组件能够接收并处理该Intent时,才使用隐式Intent。需要注意的是,为了保证App的安全,我们应该始终使用显式的Intent来启动Service,并且不要为Service设置任何Intent Filter。通过隐式Intent 启动Service 是有风险的,因为你不确定哪个App 中的哪个Service 最终会启动来响应你的隐式Intent。更悲惨的是,由于Service在后台运行,没有UI,用户不知道哪个Service在运行。
Intent组成
MIME TYPE
在学习Intent的组成部分之前,我们先了解一下基础知识:MIME TYPE。
什么是MIME TYPE
MIME类型的缩写是(多用途互联网邮件扩展),代表互联网媒体类型。 MIME 使用简单的字符串组成,最初用于识别电子邮件附件的类型。媒体类型通常由Web服务器通过HTTP协议告知浏览器,更准确的说是用Content-Type来表示,比如:
内容类型: 文本/HTML
MIME 类型可以包含视频、图像、文本、音频、应用程序和其他数据。
MIME TYPE组成
通常只有一些在Internet 上广泛使用的格式才会获得MIME 类型。如果是客户端定义的格式,一般只能以application/x-开头。例如,application/vnd.ms-excel 指定Microsoft Excel 文件类型。
每个MIME 类型都由两部分组成。第一部分是数据的一般类别,如声音音频、图像等,第二部分定义了具体类型。
对于常见的MIME 类型,请参阅MIME 参考手册。
MIME Type通配符
标准MIME类型为同一资源的不同格式指定了不同的MIME类型。例如图像资源的MIME类型包括image/bmp、image/cis-cod、image/gif、image/ief、image/jpeg、image/pipeg.如果需要指定通用类型,比如指定所有图像资源,都可以使用通配符组成image/*。
MIME Type作用
将输出发送到浏览器时,浏览器必须启动适当的应用程序来处理输出文档。这可以通过根据MIME 类型确定启动哪个程序来处理。在HTTP 中,MIME 类型在Content-Type 标头中定义
Android MIME Type
Android MIME Type类型
标准MIME 类型
定制
稍后将在Intent 组件元素中介绍属性。定制的MIME 类型格式也有要求。定制方法涉及到ContentProvider,下次仔细阅读。
MIME Type参考
了解Android 中的MIME 类型
什么是MIME 类型?
如何处理android中使用的MimeType
Intent组成部分
Android可以根据Intent携带的信息找到要启动的组件。 Intent中还携带了一些数据信息,以便待启动的组件根据Intent中的数据进行相应的处理。
Intent由6部分信息组成:Component Name、Action、Data、Category、Extras、Flags。按其功能可分为以下三种:
组件名称、操作、数据和类别决定Android 将启动哪个组件。 Component Name 用于显式Intent,Action、Data、Category、Extras 和Flags 用于隐式Intent。 Extras,包含组件实际处理时使用的特定数据信息。 Flags是Intent的元数据,决定了Android关于其操作的一些行为。
Component Name
要启动的组件的名称。一般情况下,显示Intent中会指定要启动的组件类文件的参数,即Component Name。如果没有设置组件名称,那么这个Intent是隐式的,Android系统会根据其他Intent信息(比如action、data、category等)进行一些比较和判断,来决定最终启动哪个组件。因此,如果您在自己的应用程序中启动组件,则应该通过指定组件名称(因为您知道组件的完整类名)来通过显式Intent 启动它。
应该注意的是,启动服务时,您应该始终指定组件名称。否则你不确定最终启动了哪个App的哪个组件,用户也看不到启动了哪个Service。
Component Name参数指定
Intent中组件名称对应的字段是ComponentName对象。您可以通过要启动的组件的完整类名(包括应用程序的包名)来指定该值,例如com.example.ExampleActivity。您可以通过Intent 的setComponent() 方法、setClass() 方法、setClassName() 方法或Intent 的构造函数来指定组件名称。
Action
是一个字符串,表示要执行的操作,例如查看或选择,对应于Intent Filter中的action标签。
Action定义
可以预定义或自定义操作。 Android中的Intent类和其他框架级类也提供了许多具有某些一般含义的已定义操作。
定制就是指定一个唯一的action,方便你的App中使用Intent,或者通过其他App中的Intent来调用你App中的组件。
如果您自定义动作,请务必使用应用程序的包名作为动作的前缀。这是避免混乱的良好编程习惯。
设定Action
通过调用intent对象的setAction()方法或者在intent的构造函数中指定intent的动作。注意Intent只能由一个action。
Data
Intent中的数据指的是Uri对象以及数据的MIME类型,对应于Intent Filter中的数据标签。
Uri
一个完整的Uri由scheme、host、port、path组成,格式为://:/。 Uri就像一个数据链接,组件可以根据这个Uri获取最终的数据源。 Uri通常与action结合使用。例如,如果我们将操作设置为ACTION_VIEW,则应该提供要编辑的文档的Uri。
Android 有很多预定义的模式,包括内容协议、http 协议、文件协议、用于打电话的tel 协议、用于地理位置的geo 协议……
MIME Type
Android 会根据Uri 和MIME 类型将Intent 传递给符合条件的组件。例如,指定MIME Type后,可以防止Android错误地将包含视频Uri的Intent对象传递给只能显示图片的Activity。
如果Uri使用content:协议,那么这意味着Uri提供的数据将来自本地设备,即数据由ContentProvider提供。在这种情况下,Android将根据Uri自动推断MIME类型。在这种情况下,我们不需要自己做。指定MIME 类型。因为这个Uri的类型可以通过provider的getType(Uri)方法获取。
设置Data
如果只设置数据的Uri,则需要调用Intent对象的setData()方法;如果只设置数据的MIME类型,则需要调用Intent对象的setType()方法;如果要同时设置数据的Uri和MIME类型,则需要调用Intent对象的setDataAndType()方法。
需要注意的是,如果要同时设置数据的Uri和MIME类型,不要依次调用Intent对象的setData()方法和setType()方法,因为setData()方法和setType () 是互斥的,即如果调用setData() 方法会将Intent 中setType() 方法设置的MIME 类型重置为空。如果调用setType()方法,Intent中已经通过setData()方法设置的Uri将会被重置为空。因此,当需要同时设置数据的Uri和MIME类型时,必须调用Intent对象的setDataAndType()方法,而不是分别调用setData()方法和setType()方法。
Category
类别包含一些有关组件如何处理Intent 的附加信息。同时,可以更准确地定位符合条件的元件。您可以在Intent 类中找到更多预定义类别。
当调用startActivity()或startActivityForResult()方法时,category.DEFAULT会自动添加到参数Intent中。所以将这个类别添加到对应的IntentFilter中。
Extras
附加数据信息。 Intent中有一个Bundle对象,用于存储各种键值对。接收到Intent的组件可以从中读取所需的信息,完成相应的工作。有些Intent依赖Uri来承载数据,有些Intent则依赖extras来承载数据信息。
定义Extra的键值
Intent 类还以EXTRA_* 的形式指定许多预定义的附加项。您还可以声明您自己的自定义额外内容。请确保应用程序的包名称作为您的extra 的前缀。
设置Extra
通过调用Intent对象的各种重载的putExtra(key, value)方法,以键值对的形式向Intent中添加各种附加数据。也可以直接创建一个Bundle对象,向Bundle对象传入很多键值对,然后通过调用Intent对象的putExtras(Bundle)方法将它们设置到Intent对象中。
Flags
标志表示标记。 Intent类中定义的flag可以作为Intent对象的元数据。这些标志会告诉Android系统如何启动该Activity(例如,新启动的Activity属于哪个任务)以及启动后如何处理该Activity(例如)。有关详细信息,请参阅Intent 的setFlags() 方法。
实践
mImageUri=Uri.fromFile(outPutImage);
意图intent=new Intent();
Intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
startActivityForResult(意图,TAKE_PHOTO); imageUri 指定图像存储的Uri,作为额外,让相机在拍照后知道照片的存储位置信息。
使用隐式Intent最佳方式
使用隐式Intent启动组件时,如果Android系统没有对应的组件,则会抛出异常。因此,在启动组件时首先要判断Android系统是否至少有一个组件满足Intent条件。判断的方法有两种:PackageManager中的方法和Intent类中的方法。
这两个方法将允许Android根据sendIntent查找适合启动的潜在组件的信息,并将结果以ResolveInfo类的对象的形式返回。如果返回null,则说明当前系统中没有任何组件可以接收并处理该Intent。如果返回不为null,则表明系统中至少有一个组件可以接收并处理该Intent。
PackageManager
PackageManager pm=getPackageManager();
//为什么参数flag被赋值0,我不知道
if(pm.resolveActivity(intent, 0) !=null) {
启动活动(意图);
}参数Flag用于指定搜索方式。文档中有一句话:最重要的是MATCH_DEFAULT_ONLY,将解析限制为仅那些支持CATEGORY_DEFAULT的活动。指定MATCH_DEFAULT_ONLY 标志用于搜索包含CATEGORY_DEFAULT 类别的组件。
该方法通常用于判断是否存在满足条件的组件。该标志通常设置为0。我不知道为什么。我个人的理解可能是多个flag通过按位或形成一个flag。此处该标志设置为0。与原标志进行按位或运算时,原标志不改变,即保持默认。如有错误,请指出,纯属无稽之谈。
Intent
if(intent.resolveActivity(getPackageManager()) !=null) {
启动活动(意图);
}
App Chooser
当使用隐式Intent时,Android系统中可能有多个组件满足该Intent的条件。第一次打开时,会弹出一个选择器供用户选择。用户可以检查以始终将其中之一设为默认启动组件。这样下次启动时就会默认打开选中的组件。然而,如果用户想要共享一个文件,他们不一定只使用一个应用程序来共享它,所以在这种情况下我们应该强制选择器每次都打开,让用户选择。
Intent=Intent.createChooser(intent, "选择WebKit");
if(intent.resolveActivity(getPackageManager()) !=null) {
启动活动(意图);
}这里调用Intent类中的静态方法createChooser()创建一个选择器Intent,并每次启动该Intent。
Intent过滤
设置隐式Intent的参数后,需要匹配所有组件的IntentFilter中的参数,找到符合条件的组件。
IntentFilter
是Intent过滤器。一个组件可以包含0 个或多个Intent Filter。 Intent Filter写在App的manifest文件中。它通过设置action或uri数据类型来指定组件可以处理的Intent类型。如果您为您的Activity 设置Intent Filter,则其他应用程序可以通过隐式Intent 启动您的Activity。
当Android系统收到启动某个Activity(或其他组件)的隐式Intent时,Android会根据以下三个信息将该Intent信息与已注册组件的intent-filter信息进行比较,选择最匹配的Intent 。活动(或其他组件):
Intent中的action Intent中的category Intent中的数据(包括Uri和MIME类型的数据),即隐式Intent对象必须满足目标组件中注册的intent-filter的三个标签中的信息才能被启动。
IntentFilter示例
Action测试
如果想让intent对象通过action测试,intent-filter中声明的action不能为空,并且必须包含intent对象中的action值(如果intent的action值不为空) 。如果intent-filter没有声明任何action,那么所有的intent对象(即无论intent如何配置)都无法通过intent-filter的action测试。
Category测试
如果intent对象不包含任何类别,并且该intent不用于启动Activity,则该intent对象始终可以通过任何intent-filter的所有类别测试;如果intent对象包含类别(至少一个),则只有当intent-filter中声明的所有类别都包含该intent对象中的所有类别时,类别测试才通过。如果Activity允许通过隐式Intent启动,那么我们必须在Activity的intent-filter中声明值为android.intent.category.DEFAULT的类别。 android.intent.category.DEFAULT 的类别。这是因为当我们向startActivity() 或startActivityForResult() 方法传递隐式Intent 时,Android 会自动将android.intent.category 的值添加到隐式Intent 中。 DEFAULT类别,所以为了让intent-filter包含intent中的所有类别,我们需要将category添加到activity的intent-filter中,使用时需要特别注意。
Data测试
在IntentFilter中设置data属性的uri值时,使用uri的通配符和。其中*匹配任意字符串,#匹配任意数字。
关于Android中Intent对象和Intent Filter之间的过滤匹配过程的详细解释可以参考博客。
【深入解析Android应用间交互:Intent技术详解】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
终于明白 Android 里程序怎么互相传递信息了!
有17位网友表示赞同!
看了很多教程才懂这个 Intent 的概念,还挺复杂的。
有6位网友表示赞同!
学习安卓开发还得花时间了解这些系统级别的知识啊。
有10位网友表示赞同!
感觉 Intent 就是 Android app 连接的桥梁吧。
有15位网友表示赞同!
之前写 App 经常不知道怎么实现组件之间的交互,现在明白了!
有12位网友表示赞同!
Android 开发环境挺复杂的,需要学习很多东西。
有15位网友表示赞同!
学习这种概念很有用,以后开发 App 会更容易一些!
有13位网友表示赞同!
这篇文章写的很通俗易懂,让我更理解了 Intent 的用法。
有10位网友表示赞同!
感觉 Android 真是个强大的平台,可以做 so 多事!
有5位网友表示赞同!
这个 Intent 可以用来实现很多 cool 的功能,值得研究。
有5位网友表示赞同!
我要学习一下怎么用 Intent 实现 App 之间的分享功能!
有20位网友表示赞同!
看了这篇文章以后觉得安卓开发很有潜力啊。
有17位网友表示赞同!
Android 这么强的手机系统,也需要这些基础的知识支撑!
有13位网友表示赞同!
这篇关于 Intent 的文章值得推荐给想学 Android 的人。
有7位网友表示赞同!
学习编程一直都是个不断挑战的过程!
有13位网友表示赞同!
明白了 Intent 的用法之后,我的安卓开发之路就更顺畅了!
有9位网友表示赞同!
Android 的未来一定一片光明,这个平台发展得越来越成熟!
有9位网友表示赞同!
这篇文章让我对 Android 开发有了更深入的了解。
有7位网友表示赞同!
想成为一名优秀的 Android 开发者,这些基础知识不可或缺!
有9位网友表示赞同!
感觉科技进步的速度真快,Android 的新功能让人眼前一亮!
有18位网友表示赞同!