当我们用一个显式 Intent 去启动组件时,Android 会根据 Intent 对象所提供的 component name 直接找到要启动的组件,当我们用一个隐式的 Intent 去启动组件时,Android 系统就无法直接知道要启动的组件名称了。
Intent intent = new Intent(this, xxx.class);startActivity(intent);
使用隐式 Intent 之前需要在 AndroidManifest.xml 中对标签增加设置。
<activity android:name="..IntentActivity"> <intent-filter> <action android:name="com.luyai.action.TEST" /> </intent-filter></activity>
使用隐式 Intent 跳转 Activity。
Intent intent = new Intent("com.luyai.action.TEST");startActivity(intent);
如果 Intent 中的存在 category 那么所有的 category 都必须和 Activity 过滤规则中的 category 相同。才能和这个 Activity 匹配。Intent 中的 category 数量可能少于 Activity 中配置的 category 数量,但是 Intent 中的这 category 必须和 Activity 中配置的 category 相同才能匹配。
<activity android:name=".ui.activity.IntentActivity"> <intent-filter> <action android:name="com.luyai.action.TEST" /> <category android:name = "android.intent.category.DEFAULT" /> <category android:name="xxx.xxx.xxx"/> </intent-filter></activity>
运行以下代码可以匹配到 IntentActivity:
Intent intent = new Intent("com.luyai.action.TEST");intent.addCategory("xxx.xxx.xxx");startActivity(intent);
只通过 category 匹配是无法匹配到 IntentActivity 的,因为 category 属性是一个执行 Action 的附加信息。
Android 中的 Scheme 是一种页面内跳转协议,是一种非常好的实现机制。通过定义自己的 Scheme 协议,可以非常方便跳转 App 中的各个页面。
使用场景:
<scheme> :// <host> : <port> [<path>|<pathPrefix>|<pathPattern>]
设置 Scheme
在 AndroidManifest.xml 中对标签增加设置 Scheme。
<activity android:name=".ui.activity.SchemeActivity" android:screenOrientation="portrait"> <!--Android 接收外部跳转过滤器--> <!--要想在别的 App 上能成功调起 App,必须添加 intent 过滤器--> <intent-filter> <!--协议部分配置,注意需要跟 web 配置相同--> <data android:scheme="aa" android:host="bb" android:port="1024" android:path="/from"/> <!--下面这几行也必须得设置--> <category android:name="android.intent.category.DEFAULT" /> <!--表示 Activity 允许通过网络浏览器启动,以显示链接方式引用,如图像或电子邮件--> <category android:name="android.intent.category.BROWSABLE" /> <action android:name="android.intent.action.VIEW" /> </intent-filter></activity>
原生调用:
Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);startActivity(intent);
网页调用:
<a href="aa://bb:1024/from?type=jeanboy">打开 App</a>
在 SchemeActivity 中可以处理 Scheme 跳转的参数:
public class SchemeActivity extends AppCompatActivity {
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); Uri uri = getIntent().getData(); if (uri != null) { //获取指定参数值 String type = uri.getQueryParameter("type"); Log.e("SchemeActivity", "type:" + type);
if(type.equals("jeanboy")){ ActivityUtils.startActivity(XXXActivity.class); }else if(type.equals("main")){ ActivityUtils.startActivity(MainActivity.class); } } finish(); }}
判断一个 Scheme 是否有效:
PackageManager packageManager = getPackageManager();Uri uri = Uri.parse("aa://bb:1024/from?type=jeanboy");Intent intent = new Intent(Intent.ACTION_VIEW, uri);List<ResolveInfo> activities = packageManager.queryIntentActivities(intent, 0);boolean isValid = !activities.isEmpty();if (isValid) { startActivity(intent);}