Android通过URL打开Activity

公众号:码农乐园 等级 675 1 0

关注公众号 QXF069

为每个 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

这样,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 如下:

接下来就是去修改需要绑定 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 的范畴,这边就直接贴个链接。

http://t.cn/RqMTBDZ

http://t.cn/RzOQWGU

App 内应用场景 除了第三方 app 跳转场景外,还可以在 app 内部 Activity 跳转时采用 Router 来实现,比如在 Android 端和后端约定好页面对应的 url,后端在发送 push 的时候,就可以发送特定的 url,客户端只需要处理打开 url 即可,可以有效减少 push 通知的适配工作。相关 API 如下:

Routers.open(Context, String) Routers.open(Context, Uri)

收藏
评论区

相关推荐

Android Activity生命周期,启动模式,启动过程详解
前言 接触过Android开发的同学都知道Activity,Activity作为Android四大组件之一,使用频率高。简单来说Activity提供了一个显示界面,让用户进行各种操作,本文主要分为以下三个部分:Activity的生命周期,启动模式,以及Activity的工作过程。文中大部分篇幅来自《Android开发艺术探索》一书,尽管想多以流程或图
Android通过URL打开Activity
关注公众号 QXF069 为每个 Activity 绑定一个 url 可以方便的让第三方 app 直接打开这些 Activity。也可以方便在 app 内部进行页面跳转,解耦。 背景 举一个常见的案例,假设我们有个产品 A,产品 A 包含 h5 网页端和客户端,当用户在手机打开我们的 h5 网页端的时候,我们会期望如果用户手机安装了我们的客户端,则直接打
Android Fragment生命周期
Fragment 是在 Android 3.0 中引入,用于解决不同屏幕分辨率的设备上 UI 显示、交互的问题。Fragment 有自己的布局,有自己的生命周期,有自己的事件响应。 但 Fragment 又是依赖于 Activity 存在的,你可以把多个 Fragment 嵌入到一个 Activity 中或者多个 Activity 重用一个 Fragmen
Activity的启动方式和flag详解
**Activity的4种状态:** **活动的**:当一个Activity在栈顶,它是可视的、有焦点、可接受用户输入的。Android试图尽最大可能保持它活动状态,杀死其它Activity来确保当前活动Activity有足够的资源可使用。当另外一个Activity被激活,这个将会被暂停。 **暂停**:在很多情况下,你的Activity可视但是它没有焦
034 Android NavigationView和DrawerLayout实现抽屉式导航设计(侧边栏效果)
**1.创建带侧滑效果的activity** ![](https://oscimg.oschina.net/oscnet/333199cfe89b2025778b04b97a9ec41f2d7.png) 右击,new---->activity---->选择NavgationDrawer Activity **2.xml文件布局** (1)activi
Activity Lifecycle
官方介绍网址:[http://developer.android.com/reference/android/app/Activity.html](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fdeveloper.android.com%2Freference%2Fandroid%2Fapp
Activity猫的一生
大家好,关于Android中Activity的生命周期,网上大多数文章基本都是直接贴图、翻译API,比较笼统含糊不清。 ![](https://static.oschina.net/uploads/img/201703/28130413_Fi8i.png) **我就用故事来说一说:** 有个人叫User,TA养了几只猫,有只猫叫Activity。Use
Activity跳转通过EventBus传值问题
根据阿里发布的Android开发规范:下载地址:[https://102.alibaba.com/downloadFile.do?file=1520478361732/Android\_v9.pdf](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2F102.alibaba.com%2Fdow
Android 使用intent传递返回值:startActivityForResult()与onActivityResult()与setResult()参数分析,activity带参数的返回
在一个父Activity通过intent跳转至多个不同子Activity上去,当子模块的代码执行完毕后再次返回父页面,将子activity中得到的数据显示在主界面/完成的数据交给父Activity处理。这种带数据的intent跳转需要使用activity的onActivityResult()方法。 **(1)startActivityForResult([
Android 复选框 以及回显
activity\_main.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http:/
Android 插件化原理解析——Activity生命周期管理
在Java平台要做到动态运行模块、热插拔可以使用`ClassLoader`技术进行动态类加载,比如广泛使用的`OSGi`技术。在Android上当然也可以使用动态加载技术,但是仅仅把类加载进来就足够了吗?`Activity`,`Service`等组件是有生命周期的,它们统一由系统服务`AMS`管理;使用`ClassLoader`可以从插件中创建Activit
Android 面试常问七道题
1Android的四大组件以及作用 **Activity**:Activity是Android程序与用户交互的窗口,是Android构造块中最基本的一种,它需要为保持各界面的状态,做很多持久化的事情,妥善管理生命周期以及一些跳转逻辑。 **service**:后台服务于Activity,封装有一个完整的功能逻辑实现,接受上层指令,完成相关的动作,
Android开发,你应该知道的
学习Android应用开发大约一年多时间,这是在工作中常用的一些开发知识的整理汇总,由于涉猎范围所限,定有不足之处,欢迎大家通过微博([@Cundong](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fweibo.com%2Fliucundong))与我交流。 **1、Activity生命
Android面试收集录18 Android Context详解
Activity mActivity =new Activity() 作为Android开发者,不知道你有没有思考过这个问题,Activity可以new吗?Android的应用程序开发采用JAVA语言,Activity本质上也是一个对象,那上面的写法有什么问题呢?估计很多人说不清道不明。Android程序不像Java程序一样,随便创建一个类,写个main(
JFinal使用笔记5
1、前台代码 $.ajax({ type : "POST", url : "/activity", dataType : "json", success : function(data) { alert("success"); conso