给隐式Intent加载运行检查(Android Development Patterns S1 Ep 1)
2016-09-26 01:14
435 查看
前言
2015年9月开始,谷歌在YouTube上上传了一系列开发指导视频,这是Android Development Patterns系列视频的第一期,标题为“Protecting Implicit Intents with Runtime Checks”Intent 类型
Intent 类型Intent 分为两种类型:
显式 Intent :按名称(完全限定类名)指定要启动的组件。通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务的类名。例如,启动新 Activity 以响应用户操作,或者启动服务以在后台下载文件。
隐式 Intent :不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理它。例如,如需在地图上向用户显示位置,则可以使用隐式 Intent,请求另一具有此功能的应用在地图上显示指定的位置。
创建显式 Intent 启动 Activity 或服务时,系统将立即启动 Intent 对象中指定的应用组件。
创建隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。Intent如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并将其传递给对象。如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
Intent 过滤器是应用清单文件中的一个表达式,它指定该组件要接收的 Intent 类型。例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。
警告:为了确保应用的安全性,启动 Service 时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService(),系统会抛出异常。
[1] Activity A 创建包含操作描述的 Intent,并将其传递给 startActivity()。
[2] Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。
[3] 找到匹配项之后,该系统通过调用匹配 Activity(Activity B)的 onCreate() 方法并将其传递给 Intent,以此启动匹配 Activity。
隐式 Intent 示例
应用1:My Application
应用2:Implicit Intent
在应用1中点击
Implicit Intent按钮,发起隐式Intent,跳转到应用2。
构建隐式 Intent
如需声明对于应用接收的 Intent ,请确保将应用的软件包名称作为前缀。My Application中,Button代码如下:
static final String IMPLICIT_INTENT = "com.example.journey.IMPLICIT_INTENT"; Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent sendIntent = new Intent(); sendIntent.setAction(IMPLICIT_INTENT); startActivity(sendIntent); } });
接收隐式 Intent
要公布应用可以接收哪些隐式 Intent,请在清单文件中使用 <intent-filter> 元素为每个应用组件声明一个或多个 Intent 过滤器。每个 Intent 过滤器均根据 Intent 的操作、数据和类别指定自身接受的 Intent 类型。仅当隐式 Intent 可以通过 Intent 过滤器之一传递时,系统才会将该 Intent 传递给应用组件。注意:显式 Intent 始终会传递给其目标,无论组件声明的 Intent 过滤器如何均是如此。
应用组件应当为自身可执行的每个独特作业声明单独的过滤器。例如,图像库应用中的一个 Activity 可能会有两个过滤器,分别用于查看图像和编辑图像。 当 Activity 启动时,它将检查 Intent 并根据 Intent 中的信息决定具体的行为(例如,是否显示编辑器控件)。
Implicit Intent中,
Manifest.xml文件声明如下
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.journey.implicitintent"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".ScrollingActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <action android:name="com.example.journey.IMPLICIT_INTENT"/> <category android:name="android.intent.category.LAUNCHER"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity> </application> </manifest>
运行结果
Build Better Apps
崩溃
如果这时候我卸载了Implicit Intent这个应用,那么此时点击button按钮,应用将会崩溃。除了应用被卸载的情况外,还有以下情况会导致崩溃:
应用被禁用
用户的特定权限文件夹,不具有访问所有功能的属性
管理员限制了用户关于某些应用和属性的使用权限
解决办法
使用resolveActivity
Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent sendIntent = new Intent(); sendIntent.setAction(IMPLICIT_INTENT); // Verify that the intent will resolve to an activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(sendIntent); } } });
相关文章推荐
- Android Lolipop 屏蔽隐式Intent检查引发的错误
- 【Intent】对隐式Intent的运行时检查保护:如相机调用失败
- Android Lolipop 屏蔽隐式Intent检查引发的错误
- [置顶] android 入门基础(10) ------ intent加载手机磁盘的图片文件
- Android深入浅出系列之实例应用—开机就运行自定义的程序BroadcastReceiver和intent-filter的用法
- android Intent (隐式意图和显示意图)
- android隐式intent及启动方式
- android组件通讯 Intent Filter隐式实现Intent
- Android 隐式调用 intent
- 关于Android intent的知识 隐式意图和显示意图
- 【转】Android深入探究笔记之三 -- Intent (隐式意图和显示意图)
- Android 进程间通信 Intent机制 隐式启动Activity
- 用oralce连接.net客户端出现问题:“数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位Oracle客户端组件的情况下以64位模式运行,”的解决办法
- Android深入探究笔记 -- Intent (隐式意图和显示意图)
- Android:Intent 显示和隐式 学习
- Android深入浅出系列之实例应用—开机就运行自定义的程序BroadcastReceiver和intent-filter的用法
- android组件通讯 Intent Filter隐式实现Intent
- Android使用Intent Filter来响应隐式Intent
- 转载:用oralce连接.net客户端出现问题:“数据连接不成功,请检查该数据库是否已启动尝试加载oracle客户端时引发BadImageFormatException.如果在安装32位Oracle客户端组件的情况下以64位模式运行,”的解
- android intent 隐式调用