Weex 开发:页面跳转以及 Android 端多应用选择窗口的处理
前言
在使用Weex
开发项目的过程中,官网上面实现页面跳转的方式在iOS
端是没问题的,但是在Web
、Android
两端上面就会有问题,本文主要是将探索的过程记录一下。
页面跳转
Weex
的页面跳转,主要是通过使用 navigator 来实现,但是三端使用的过程中,因为url
的规则其实并不统一,所以需要根据不同的平台,做不同的跳转处理。在浏览器里,我们可以通过前进或者回退按钮来切换页面,Android/iOS
的 navigator 模块就是用来实现类似的效果,除了前进、回退功能,该模块还允许我们指定在切换页面的时候是否应用动画效果,使用方式如下代码所示:
Web端
Web
端其实最好处理,只需要将路径设置为目标vue文件的文件名,再加上.html即可,比如从登录页面Login.vue
跳转到注册页面Register.vue
,代码可以这样写,如下所示:
Android端
Android
端的跳转方案,官方文档并没有详细说明,对于新人来说,根本就无从下手。首先,我们查看Android
端的源码,可以发现,SplashActivity
是用于实现闪屏页的,在AndroidManifest.xml
文件中,有如下设置:
在闪屏页旋转动画结束后,跳转到了WXPageActivity
,代码如下所示:
很明显,WXPageActivity
就是代理所有Weex
页面的渲染的Activity
。
在WXPageActivity
中,我们运行Weex
的官方Demo
,可以发现Weex
项目在闪屏页结束后,跳转到的页面,也就是如下图所示:
这个页面的url
其实就是file://assets/index.js
,源码如下所示:
由此可以得出,Android
的跳转uri
是以file
开头的路径,而且打包的js
文件是存放在Android
端代码的assets
文件夹下。
这个时候,我们知道了Android
端的跳转uri
制定规则,是不是就可以解决并完成Android
端的页面跳转功能了?其实不是。
在Weex
上使用 navigator 时,Android
端需要做的事情是注册IntentFilter
,具体情况可以查看sdk源码:com.taobao.weex.appfram.navigator.WXNavigatorModule
类。
因此,我们对能够加载Weex-js
页面的Activity
需要在AndroidManifest.xml
中进行清单文件的注册,使之能够响应隐式意图,所以我们需要在WXPageActivity
中加入如下代码:
接着,我们需要在WXPageActivity
中看到如下代码:
可知,uri
就是所传入的js
文件路径地址,也就是说,我们要新增判断,只要将mUri=uri
即可实现这个页面在Activity
里的渲染,为了识别传入的js
文件路径地址,并且能够处理启动页index.vue
的逻辑,将WXPageActivity
中的代码:
更改为:
至此,使用Weex
时实现了Android
端页面跳转的功能,比如从登录页面Login.vue
跳转到注册页面Register.vue
,代码可以这样写,如下所示:
Android 7.0 以上,使用以上方案Weex页面无法成功跳转的问题
因为从Android 7.0
开始,一个应用提供自身文件给其他应用使用时,如果给出一个file://
格式的URI
的话,应用会抛出FileUriExposedException
异常,这是由于Google
认为目标App
可能不具有文件权限,会造成潜在的安全问题,所以让这一行为快速失败。解决方案是,只需在Android
端代码WXApplication
文件的onCreate()
方法中加上如下代码即可:
Android端多应用选择窗口的处理
我们知道,navigator 的跳转是一个
Android
的startActivity
的过程,所打开的Activity
就是写有拦截器的Activity
。所谓的拦截器,其实就是将一段标签代码
<intent-filter><intent-filter/>
放到AndroidManifest.xml
的<activity>
标签下。而拦截器是跨应用的,当我们手机中安装了多个利用Weex
开发的手机应用的时候,总是会尴尬的弹出一个应用选择框,这是因为当一个手机中有多个带有相同拦截器的Activity
的时候,Android
系统就会让我们选择进入到哪个Activity
中。一旦用户不小心点击到别人的应用甚至设置了默认的时候,就会错乱了数据配置。如果
Intent
中的存在category
,那么这些category
都必须和Activity
过滤规则中的category
相同,才能和这个Activity
匹配。Intent
中的category
数量可能少于Activity
中配置的category
数量,但是Intent
中的这category
必须和Activity
中配置的category
相同才能匹配。通俗的讲就是,比如Intent
中有3个category
,activity
的过滤规则中有5个category
,那intent
中的3个category
需要是activity
的过滤规则中有5个category
中的3个,若有任意一个未出现在这5个里面,匹配就会失败。我们在
nativie
触发了js
的Click
事件之后,由js
通过主动WXModule
向Android
通信,传递相应的信息如链接地址、参数信息等等,Android
收到这些信息后通过Activity
跳转加载对应的地址,也就是说由js
进行的跳转工作全权委托给Native
进行处理,可以通过隐式意图、显示意图跳转皆可。由上可知,Weex官方sdk里默认的Intent设置如下所示:
只是设置了Category
为:com.taobao.android.intent.category.WEEX
,这样,当我们在AndroidManifest.xml
文件中的WXPageActivity
添加:
时,是可以完成页面跳转功能的,只是这是官方默认的过滤规则,也就是意味着,如果手机安装多个Weex
开发的应用程序,在页面跳转的时候,就会出现多个Weex
应用响应隐式意图,然后Android
系统就会出现多应用选择窗口。所以这里,将Category
更改为:com.moon.android.intent.category.WEEX
,使之唯一,也就是,只能响应本应用程序中的WXPageActivity
。
解决Android端多应用选择窗口的问题,步骤如下所示:
1.新建TestModule
类,代码如下所示:
2.在WXApplication
中注册TestModule
,代码如下所示:
3.在vue
文件中使用,代码如下所示:
写在最后
接触Weex
快两年了,参与开发了公司里的两个项目,总的来说,跨平台相比原生开发,在效率方面提升确实很明显,很多样式一两行代码就可以了,但如果是使用Android
原生来开发,光写XML
都很费时间了,当然Weex
也有不足之处,就是在与各端交互的过程中,需要兼容,所以很容易出现各种问题,比如本文提到的页面跳转,就是一个很棘手的问题,至少对我来说是如此,因此,也是想要将一些心得记录下来,也算是接触Weex
以来,给自己留一点念想,后续不打算投入精力到Weex
方面,而是Flutter
,从18年知道Flutter
,就很看好,现在发展迅速,越发壮大了。
版权声明: 本文为 InfoQ 作者【brave heart】的原创文章。
原文链接:【http://xie.infoq.cn/article/f09d47e7ab4e259892071a309】。文章转载请联系作者。
评论 (4 条评论)