通过 URL 打开 Activity
为每个 Activity 绑定一个 url 可以方便的让第三方 app 直接打开这些 Activity。也可以方便在 app 内部进行页面跳转,解耦。
背景
举一个常见的案例,假设我们有个产品 A,产品 A 包含 h5 网页端和客户端,当用户在手机打开我们的 h5 网页端的时候,我们会期望如果用户手机安装了我们的客户端,则直接打开 app,否则停留在网页端浏览。
这是一个很常见的需求,但是实现需要 h5 和 Android 的配合,本文会先说下原理,然后单独描述 Android 端需要做的事情,最后会给一个链接说明 h5 的工作。
原理
Android 端先给 Activity 绑定一个 url ,比如说是 myapp://main
.
用户访问 http://myapp.com
网页时,h5 尝试访问 myapp://main
,如果用户安装了客户端,则会打开相应的 Activity,否则会继续留在 h5 浏览网页。
那么,如何给 Activity 绑定一个 url 是在 Android 端的关键。
Android 实现
创建一个空的 ViewActivity.
public class ViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
在 AndroidManifest.xml
里面注册 ViewActivity,包含一个 action 为 android.intent.action.VIEW
的 intent-filter
<activity
android:name=".ViewActivity"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
</activity>
这样,ViewActivity
就具备了接收 myapp
协议的 android.intent.action.VIEW
事件的能力。比如说,如果某个 app 执行了下面的这段逻辑,我们的 ViewActivity 就可能被打开。
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("myapp://dosomething"));
startActivity(intent);
刚才之所以说 "可能被打开",是为了严谨。因为完全可能用户手机上,还有另外一个 app 也声明了一样协议的 intent-filter. 这时候系统就会给出一个弹出框,让用户选择一个期望的应用来打开该地址。
既然入口找到了,接下来就简单了,无非就是实现一下 ViewActivity 处理跳转逻辑,比如这样。
public class ViewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Uri uri = getIntent().getData();
String url = uri.toString();
if ("myapp://main".equals(url)) {
startActivity(new Intent(ViewActivity.this, MainActivity.class));
} else if ("myapp://user".equals(url)) {
startActivity(new Intent(ViewActivity.this, UserActivity.class));
}
finish();
}
}
但是上面这种,这是一个理想的情况,因为现实情况会复杂的多。比如说会遇到传参问题,打开一个 UserActivity 可能都是需要指定一个 userId 的。不过再怎么复杂,无非就是对一个 url 的解析。
下面会介绍一个我写的开源项目,省掉了解析 url 的麻烦,下面会基于这个库来说明。
库
这个库叫 ActivityRouter,通过给 Activity 添加注解来绑定 url. 首先我们要把库添加到项目里面来, 需要修改两个 build.gradle 文件。
项目根目录的 build.gradle
buildscript {
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.7'
}
}
app 项目的 build.gradle
apply plugin: 'android-apt'
dependencies {
compile 'com.github.mzule.activityrouter:activityrouter:1.1.1'
apt 'com.github.mzule.activityrouter:compiler:1.1.1'
}
这样,等项目 sync 完 ActivityRouter 就已经被集成在项目里面了。
此外还需要改一个配置,之前在 AndroidManifest.xml
上注册的 ViewActivity 现在要换成 ActivityRouter 里面自带的 Activity,这样 ActivityRouter 才有机会处理相关的 Intent 事件。修改完的 AndroidManifest.xml
如下:
<activity
android:name="com.github.mzule.activityrouter.router.RouterActivity"
android:theme="@android:style/Theme.NoDisplay">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" />
</intent-filter>
</activity>
接下来就是去修改需要绑定 url 的 Activity,添加注解即可,一个典型的实现如下:
@Router("main")
public class MainActivity extends Activity {
}
一个需要参数的 Activity 可以这样声明:
@Router("user/:userId") // :userId 代表参数名为 userId
public class UserActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String userId = getIntent().getStringExtra("userId"); // 获取参数 userId
}
}
也可以给参数指定类型,比如说常见的 id 为 long 型.
@Router(value = "user/:userId", longExtra = "userId")
这样我们就可以通过 myapp://main
来访问 MainActivity, myapp://user/89757
来访问 UserActivity 并且 userId = 89757 了。
H5 实现
如上文所说网页自动跳转到 app 需要 h5 配合,由于 h5 已经超越了 Android 的范畴,这边就直接贴个链接。
App 内应用场景
除了第三方 app 跳转场景外,还可以在 app 内部 Activity 跳转时采用 Router 来实现,比如在 Android 端和后端约定好页面对应的 url,后端在发送 push 的时候,就可以发送特定的 url,客户端只需要处理打开 url 即可,可以有效减少 push 通知的适配工作。相关 API 如下:
Routers.open(Context, String)
Routers.open(Context, Uri)
结语
哈哈,感谢你看到这里。
通过 URL 打开 Activity的更多相关文章
- Unity3D研究院之打开Activity与调用JAVA代码传递参数
原地址:http://www.xuanyusong.com/archives/667 Unity for Android 比较特殊,Unity for IOS 打包是将XCODE工程直接交给开发 ...
- 打开Activity时,不自动显示(弹出)虚拟键盘
打开Activity时,不自动显示(弹出)虚拟键盘 在AndroidManifest.xml文件中<activity>标签中添加属性 android:windowSoftInputMode ...
- Activity 事件以及如何得到新打开Activity关闭后返回的数据
1: package com.example.activity_basic; 2: 3: import android.os.Bundle; 4: import android.app.Activ ...
- 点击短信中的url打开某个应用
实现功能: 短信内容中含有url(例如,http://youngo.com/app/),点击后打开apk 遗留问题: 点击url后,会出现选择框,让用户选择是用浏览器打开还是用该apk打开----没有 ...
- Android Intent (可通过URL启动 Activity)
Intent分为两大类: (1)显性的(Explicit) (2)隐性的(Implicit) 对于隐性意图,在某些时候, 应用程序只是想启动具有某种特征的组件, 并不想和某个特定的组件耦合. 使用In ...
- crm使用url打开窗口视图
//URL可寻址元素使您能够包含指向Microsoft Dynamics CRM窗口. 视图. 对话框和其它应用程序中的报告. //这样.您就能够轻松扩展其它应用程序.报表或站点,以便用户无需切换应用 ...
- Android学习(八) 打开Activity
在Android中打开窗口有两种方式,第一种是不需要返回值的,第二种是带返回值的. Main.xml文件,程序从这个窗口开始执行. <LinearLayout xmlns:android=&qu ...
- 04_显示意图打开activity
实际上用显式意图打开一个activity就很简单了.只需要指定你要打开的这个activity的class就可以了. 需要注意一点的是创建了一个ThirdActivity必须要在清单文件里面声明.如果没 ...
- 03_隐式意图打开activity
想让第一个activity把第二个activity打开的话,在清单文件里面声明一下并且 右键Debug As Android Application居然没有报错 mimeType 讲HTML的时候就 ...
随机推荐
- 文字创作类App分享-简书
今天我用Mockplus做了一套简书App的原型,这是一款文字创作类的App,用户通过写文.点赞等互动行为,提高自己在社区的影响力,打造个人品牌.我运用了Mockplus基础组件.交互组件.移动组件等 ...
- Java并发编程73道面试题及答案
原文出处:https://blog.csdn.net/qq_34039315/article/details/7854931 1.在java中守护线程和本地线程区别? java中的线程分为两种:守护线 ...
- HDMI SCDC处理过程
SCDC State and Control Data Channel 接收端如果有SCDC,应该在E-EDID中包含一个有效的HF-VSDB,并且把SCDC_Present位设置为1.在 ...
- Latex命令
.tex代码中 | 在pdf文档中 空一行 代表回车,下一行空两格 // 代表回车,下一行顶格
- post网络请求坑
微信小程序开发中网络请求必不可少.GET.POST请求是最常用的.GET请求 POST请求的时候有好几个坑.我已经为大家填好了.
- array_filter()函数
用回调函数过滤数组中的值 array_filter(array,callbackfunction); 返回过滤后的数组
- day13_雷神_前端01
#前端 html 服务器端返回的就是一个字符串,浏览器根据html规则去渲染这个字符串. html 是超文本标记语言,相当于定义统一的一套规则,大家都遵守它,这样就可以让浏览器根据标记语言的规则去解释 ...
- Flask中的模板语言jinja2
jinja2介绍 jinja2是Flask作者开发的一个模板系统,起初是仿django模板的一个模板引擎,为Flask提供模板支持,由于其灵活,快速和安全等优点被广泛使用. jinja2的优点 jin ...
- 改善Python 程序的 91 个建议
建议1.理解Pythonic概念—-详见Python中的<Python之禅> 建议2.编写Pythonic代码 (1)避免不规范代码,比如只用大小写区分变量.使用容易混淆的变量名.害怕过长 ...
- 3.复杂的viewpager
实现这样的效果: 1.主页面布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quo ...