Skip to content
xiaojinzi123 edited this page Dec 15, 2019 · 5 revisions

设计 ProxyIntent 的目的

有些时候, 正如一位使用者提的 issue 所说的一样, 总有一些时候你是需要拿到 Intent 交给系统的, 比如小部件、通知等等.

跳转的这部分不能像自己平常跳转一样使用 Router.with(context).host("xxx").path("xxx").forward();

所以设计 ProxyIntent 的目的就是为了解决这个问题. 您可以拿到一个 Intent, 并且这个 Intent 交给系统跳转后还能最终无感的跳转到真正的目标界面

什么是 ProxyIntent

我们知道, 一般情况下, 我们使用组件化框架的路由功能都是达到了一个目的:

  • 真正的 Intent 被一个 URL 所代替, 你可以理解为你访问不到真正的 Intent, 只能通过 URL 去访问. URL 可以看做是真正的 Intent 的一个别名.

在我们 Android 中, 其实一个 Activity 的跳转其实就是一个 Intent, 只不过这个 Intent 的意图就是指向了 Activity, 整理上述所说的. 我们可以认为. URL--> Intent --> Activity

我们全程都应该直接和 URL 打交道, 而不应该绕过 URL 去拿到 Intent 或者目标的 Activity.

这时候 ProxyIntent 的作用就体现出来了. 首先. ProxyIntent 本质上是一个 Intent, 你可以通过以下方式构建出一个 ProxyIntent

Intent intent = Router.newProxyIntentBuilder()
                .host("user")
                .path("personCenter")
  		// 可省略, 省略后默认使用框架自带的无界面的 Activity
                .proxyActivity(this.getClass())
                .buildProxyIntent();

构建出来的 Intent 就是一个 ProxyIntent, 它有两部分组成:

  • 这个 ProxyIntent 的意图的目标是一个代理的 Activity. 如上面代码所示, 这个代理 Activity 可以自定义.
  • 这个 ProxyIntent 中有 跳转到真正的目标界面所需的所有的参数和数据.

整个跳转流程

当你拿到一个 ProxyIntent, 假设你创建了一个通知栏消息, 点击消息的触发的 Intent 就是刚刚你拿到的 ProxyIntent. 那么流程如下:

  • 点击消息 --> 跳转到代理 Activity

  • 代理 Activity 解析参数拿到真正的目标界面的 URL 和所需的其他数据(Bundle、flags、categories....)

  • 代理 Activity 根据上一步拿到的 URL 和所需数据发起跳转.

  • 真正的目标界面被正确的打开

其中的代理 Activity 可以是框架默认的也可以是自定义的. 如果是自定义的. 还请在 onCreate 方法和 onNewIntent() 方法中添加如下的代码:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // ......
        startProxyRouter(getIntent().getExtras());
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        startProxyRouter(intent.getExtras());
    }

    private void startProxyRouter(@Nullable Bundle bundle) {
        if (Router.haveProxyIntent(bundle)) {
            Router.with(this)
                    .withProxyBundle(bundle)
                    .forward();
        }
    }

并且你得关注你自定义的代理 Activity 的启动模式. 比如消息的触发, 代理 Activity 存在或者不存在的时候都可能触发. 我这边建议使用 singleInstance.

代码

具体的代码可以查看 Component 项目的源码中的示例模块 app 中的 MainAct 界面. 有两个按钮可以分别生成两个通知. 一个使用默认的代理 Activity, 一个使用 MainAct 为代理 Activity. 无论程序是否运行, 点击通知两者都可完成跳转.

Clone this wiki locally