IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android Activity的隐式调用(跨进程) -> 正文阅读

[移动开发]Android Activity的隐式调用(跨进程)

1.activity启动方式
Android 启动 Activity 分为两种:显式调用和隐式调用。显式调用需要明确地指定被启动对象的组件信息,包括包名和类名,而隐式调用则不需要明确指定组件信息。原则上一个 Intent 不应该既是显式调用又是隐式调用,如果二者共存的话,以显式调用为主。
显示Intent适合在同项目下使用,隐式Intent适合不同项目间的页面跳转。
显示Intent不可以跨应用使用,隐式Intent可以跨应用使用。(如果隐式Intent不需要跨应用启动,在AndroidManefests.xml中添加android:exported=false即可,exported这个属性默认值有点意思,其默认值是由activity中有无intent-filter决定的,如果有intent-filter,默认值为true,否则为false。)

2.隐式调用
隐式调用需要Intent能够匹配目标组件的IntentFilter中设置的过滤信息,如果不匹配将无法启动目前activity。这里,目标组件就是要启动的Activity,IntentFilter表示意图过滤,也被称为过滤列表。
一个IntentFilter为一个过滤列表,一个过滤列表中可以有多个过滤信息(action、catagory、data),一个Activity(目标组件)可以有多个过滤列表。
为了匹配过滤列表,需要同时匹配过滤列表中的 action、category、data 信息,否则匹配失败。一个过滤列表中的 action、category 和 data 可以有多个,所有的 action、category、data分别构成不同类别,同一类别的信息共同约束当前类别的匹配过程。只有一个 Intent 同时匹配 action 类别、category 类别、data 类别才算完全匹配,只有完全匹配才能成功启动目标 Activity。
一个 Activity 中可以有多个 intent-filter,一个 Intent 只要能匹配任何一组 intent-filter 就能成功启动对应的 Activity。

3.action 的匹配规则
action表示该activity可以执行的动作。如果跟< intent-filter>所列出的任意一个匹配的话,就说明这个activity是可以完成intent的意图的,可以将它激活。可以用setAction()为intent对象指定一个动作,也可以用getAction()读取intent对象中的动作信息。
注意:一条< intent-filter>元素至少应该包含一个< action>,否则任何intent请求都不能和该< intent-filter>匹配。一个intent只能指定一个action,但是一个目标activity可以设置多个action(即< intent-filter>中可以设置多个action属性)。

action 是一个字符串,系统预定义了一些 action,同时我们也可以定义自己的action。
action的匹配规则:
①一个intent-filter中可以有多个action,只要Intent中的action能和过滤列表中任何一个action相同就算是匹配成功。
②action 区分大小写,大小写不同字符串相同的action也会匹配失败。

4.category 的匹配规则
category用于指定当前动作(action)执行的环境,即这个activity在哪个环境中才能被激活。不属于这个环境的,不能被激活。
如果目标activity想要通过隐式调用方式激活,那么不能没有任何category设置,之前包含一个android.intent.category.DEFAULT。
一个intent只能有一个action,但是可以有多个category。同一个intent中多个category彼此间是“与”的关系,也就是说一个组件要支持全部的category才能处理该请求。

category 是一个字符串,系统预定义了一些 category,同时我们也可以自己在应用中定义自己的 category。
category匹配规则:
①Intent可以没有category,但是,如果一旦有category,那么每一个都要和过滤规则中任何一个category相同,这个是intent占主动,和action不同,action是过滤列表提供几个,让Intent选择一个,这个则是Intent有几个,那么IntentFilter中也要有,但是并没有限制IntentFilter中category的数目多少,这个可以随意只需要满足intent中需要的category就可以了。(IntentFilter中要包含Intent中全部的category,而且可以有多余的)(IntentFilter中只要有一个与Intent中的action相同即可)
②如果Intent中没有category,但是在startActivity或者startActivityForResult的时候都会默认的为Intent加上 “android.intent.category.DEFAULT”,所以必须要在IntentFilter的category中添加上< category android:name=“android.intent.category.DEFAULT”>。
所以,隐式启动的activity在Android Manefests配置中务必加上< category android:name=“android.intent.category.DEFAULT”/>
③单靠category不能进行匹配,需结合action匹配使用。

5.data的匹配规则
data表示执行时要操作的数据,即执行动作的URI,不同的动作有不同的数据规格。
如果定义了data,但intent却没有传进来指定类型的data,也不能激活该activity。
和action一样,是过滤规则占据主动。

常用的数据规格有:
http:// 表示网址
file:// 表示文件
tel:// 表示电话
mailto: 表示发送邮件
geo: 表示地理位置
content:// 表示ContentProvider

①data的结构
data 由两部分组成,mimeType和URI。
mimeType指的是媒体类型,比如image/jpeg、audio/mpeg4-generic、video/*等。

URI比较复杂结构如下:
< scheme>://< host>:< port>/[< path>|< pathPrefix>|< pathPattern>]
对比来看:
http 😕/www.baidu.com:80/search/info
或者
content://com.example.project:200/folder/subfolder/etc

(1)Scheme:URI的模式,比如:http、file、content等,如果URI中没有指定这个,那么整个URI的其它参数无效
(2)host:URI的主机名,如果host未指定,那么整个URI中的其它参数无效。
(3)port:URI中的端口号,仅当URI中指定了scheme和host参数的时候port参数才有意义。
(4)path、pathPrefix、pathPattern这三个参数可选,都表示路径,path 表示完整路径信息,pathPrefix表示路径的前缀信息,pathPattern 表示完整的路径信息,但是它里面可以包含通配符 ,空格表示 0 个或多个任意字符,遵循正则表达式的规范,如果想要表示真实的字符串,* 要写成 \*,\ 要写成 \\。

②data的匹配规则
(1)data中的URI部分可以不写,但是却有默认值,URI的默认值是content和file。
举个例子:
< intent-filter>
< data android:mimeType=“image/"/>
< / intent-filter>
这个< intent-filter>指定了媒体类型为所有类型的图片,那么 Intent 中的 mimeType 属性必须与 "image/
” 相匹配,这种情况下虽然过滤规则没有指定 URI,但是却有默认值,URI 的默认值为 content 和 file,所以 Intent 中的 URI 部分的 schema 必须为 content 或者 file 才能匹配。intent如下:
intent.setDataAndType(Uri.parse(“file://abc”), “image/png”);
(2)如果IntentFilter中定义 了< data>,那么Intent中必须要有一个可以匹配的,这就是IntentFilter占主动。
(3)如果要为 Intent 指定完整的 data,必须要调用 setDataAndType,不能先调用 setData 再调用 setType,因为这两个方法会彼此清除对方的值。
public @NonNull Intent setData(@Nullable Uri data) {
mData = data;
mType = null;
return this;
}

public @NonNull Intent setType(@Nullable String type) {
mData = null;
mType = type;
return this;
}

③如果在AndroidManifest.xml里面指定了data,那么,需要匹配到它的话,在代码里必须要设置intent的data,如intent.setData(uri)。
AndroidManifest.xml配置:
< activity android:name=".Activity">
< intent-filter>
< action android:name=“me.pwcong.demo.activity”/>
< category android:name=“android.intent.category.DEFAULT”/>
< data android:scheme=“content”
host=“pwcong.me”
port=“8080”
path="/hello"/>
< /intent-filter>
< /activity>

类文件:
Uri uri = Uri.parse(“content://pwcong.me:8080/hello”);
Intent intent = new Intent();
//可不添加category,因为默认会添加
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(uri);
startActivity(intent);

6.举例说明
①过滤列表:
< intent-filter>
< action android:name=“xlj.xlj.m”/>
< action android:name=“xlj.xlj.m.s”/>
< category android:name=“android.intent.category.DEFAULT”/>
< category android:name=“xlj.ccccc.sss”/>
< category android:name=“as.bb.cc”/>
< /intent-filter>

Intent:
Intent intent = new Intent(“xlj.xlj.m”);
intent.addCategory(Intent.CATEGORY_DEFAULT);//这个可以省略不写,因为在startActivity时会默认自动添加上
intent.addCategory("xlj.ccccc.sss);
startActivity(intent);

②过滤列表:
< intent-filter>
< action android:name=“xlj.xlj.m”/>
< action android:name=“xlj.xlj.m.z”/>
< category android:name=“android.intent.category.DEFAULT”/>
< category android:name=“xlj.ccccc.sss”/>
< data android:mimeType=“video/*”/>
< /intent-filter>

Intent:
Intent intent = new Intent(“xlj.xlj.m”);
intent.setDataAndType(Uri.parse(“file://abc”),“video/*”);
startActivity(intent);

观察可知道,如果IntentFilter中三个匹配规则都有,那么Intent的中都要涉及才可以哦。

7.如果有多个不同的Activity在AndroidManefests中配置了相同的action和category,那么执行启动方法时系统会弹出启动列表供用户选择启动哪个。
系统默认的弹出提示框,效果如下:
在这里插入图片描述
系统默认弹出框,但是咱们可以修改:
Intent intent = new Intent(“xlj.xlj.m”);
Intent chooser = Intent.createChooser(intent, “看你喜欢那个”);
startActivity(chooser);

效果如图:
在这里插入图片描述
8.如果真的找不目标ACTIVITY咋办
如果真的没有Activity,那么执行startActivity,就会出现ActivityNotFindException。
所以在隐式启动Activity中,提供了一个判断:
①PacageManager中的resolveActivity方法
PackageManager packageManager = getPackageManager();
if (packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY)!= null){
startActivity(intent);
}else {
Toast.makeText(this,“找不到你想要的activity” , Toast.LENGTH_SHORT).show();
}

因为如果找不到所需Activity,那么就会返回一个null。

②Intent 中的resolveActivity方法
if ( intent.resolveActivity(packageManager) != null){
//这个分支表示找到了目标Activity

}else {

}

9.android隐式调用所有系统的activity
// 拨打电话
intent.setAction(“android.intent.action.CALL”);
intent.setData(Uri.parse(“tel://18600012345”));

// 打开浏览器
intent.setAction(“android.intent.action.VIEW”);
intent.setData(Uri.parse(“http://192.168.1.23:8080/1.html”));

// 播放音频
intent.setAction(“android.intent.action.VIEW”);
intent.setDataAndType(Uri.parse(“file:///mnt/sdcard/Adele - Rolling in the Deep.mp3”), “audio/*”);

// 播放视频
intent.setAction(“android.intent.action.VIEW”);
intent.setDataAndType(Uri.parse(“file:///mnt/sdcard/1.mp4”), “video/*”);

// 显示图片
intent.setAction(“android.intent.action.VIEW”);
intent.setDataAndType(Uri.parse(“file:///mnt/sdcard/9.jpg”), “image/*”);

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-12 23:34:18  更:2021-10-12 23:35:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 23:26:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码