Android-Weex之多应用选择窗口处理及页面之间的跳转

来源:互联网 发布:php mysql 中文乱码 编辑:程序博客网 时间:2024/06/08 14:36

在Weex上使用openUrl或者push的方式跳转时,Android端需要做的事情是注册IntentFilter,即通过Itent的隐式意图进行跳转,详细见sdk源码中:com.taobao.weex.appfram.navigator.WXNavigatorModule类。

private final static String WEEX = "com.taobao.android.intent.category.WEEX";@WXModuleAnno    public void push(String param, final String callbackId) {        ...        Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());        intent.addCategory(WEEX);        intent.putExtra(INSTANCE_ID,mWXSDKInstance.getInstanceId());        mWXSDKInstance.getContext().startActivity(intent);        ...                     }

因此,我们对能够加载Weex-js页面的Activity需要在AndroidManifest.xml中进行清单文件的注册,使之能够响应隐式意图。

<intent-filter>    <action android:name="android.intent.action.VIEW"/>    <category android:name="com.taobao.android.intent.category.WEEX"/>    <category android:name="android.intent.category.DEFAULT"/>    <data   android:scheme="http"/>    <data android:scheme="https"/>    <data android:scheme="file"/></intent-filter>

然而问题出来了,当我们手机中安装了多个利用weex开发的手机应用的时候,总是会尴尬的弹出一个应用选择框,一旦用户不小心点击到别人的应用甚至设置了默认的时候,就会错乱了数据配置等等等等,这简直就是一个不能再尴尬的乱入……

幸好我有神器!

前几天在度娘翻阅博客的过程中,无意间发现了一个神器:一个利用weex开发的模拟淘宝购物的App香港购物GitHub源码地址,说他是神器的原因是我手机中装了3个用weex开发的App,一个是我自己的项目,一个是下载的官方Demo,另外一个就是这个香港购物App,然而这个香港购物App在页面链接跳转的时候竟然没有应用选择提示框,请注意,没有应用选择提示框!!!我甚至来不及翻阅完连载讲解Weex开发的博客,迫不及待的按照博客上说的QQ群,加进去问博主的方案。在博主的给出的他的博客链接中(没有仔细翻阅他的博客真是尴了个尬),我找到了答案。

原来博主研究深入到sdk之中,修改了sdk的源码,将隐式意图中默认的category修改为自己的category,那么这样响应的话就不会有乱入的现象了。为此,我不禁佩服博主的机智。

但是作为一个有着强迫症的我,总是想着用更完美的方案去解决,曾经想过利用反射之类的方法在Dalvik中修改被定义成final的String字符串,然而因为不是一个引用类型(即没有采用new String()的方式)而无法修改。

后来在遇到echarts的难题(weex加载echarts之后,Android端因为通过ref获取的内容并不是echarts所需的dom节点,因此无法对他进行初始化,报错信息:Cannot assign to read only property 'constructor' of [object Object]),因此决定尝试用通过Weex的Component扩展加载Android的HelloChart代替echarts方案,还有js页面需要传递指定参数拼接后缀之后Android无法识别页面等等,所以需要进行Native和Weex之间的数据交互,以此来达到Android端的无责任处理方案。

  1. Weex和Native之间的主动通信:

    这条通信方式在官网上有介绍,我就不多解释了,上代码:

    public class TestModule extends WXModule{    @JSMethod(uiThread = false)    public void getParams(...){        ...    }}

    这里需要注意的是,最好不要采用重载的方式去定义方法,因为js的弱类型在通信中无法认定参数类型因此找不到正确的方法去接收。

  2. Native和Weex之间的主动通信:

    这条通信有两种方式,第一种是我们常用的WXSDKInstance.renderByUrl通过Option穿参的方式进行主动通信,另外一种就是在Weex和Native之间的通信中再建立逆向通信即通过JSCallback,上代码:

    public class TestModule extends WXModule{    @JSMethod(uiThread = false)    public void getParams(JSCallback jscallback){        jscallback.invoke();        // jscallback.invokeAndKeepAlive();        ...    }}

    这种方案也就是说在Weex需要Native去回传参数才能继续操作,利用这种方法可以达到目的,比如页面A和页面B之间的信息传递需要传递参数,而Weex提供的Push方法中参数Options只允许携带URl地址和动画标志,此时就可以通过JSCallback在A页面收集数据在B页面回传数据,如此就可以解决了如:http://www.xx.com/index.js?id=admin这种url在Android交互中无法识别的问题了。(此方法不一定唯一,只是基于Android开发的角度谈论,如果Weex有更好的处理方案,欢迎留言指教。)

基于此,我们就可以解决多应用选择的问题了,这个问题是在页面跳转之间出现的。换一种思路,我们在nativie触发了js的Click事件之后,由js通过主动WXModule向Android通信,传递相应的信息如链接地址、参数信息等等,Android收到这些信息后通过Activity跳转加载对应的地址,也就是说由js进行的跳转工作全权委托给Native进行处理,可以通过隐式意图、显示意图跳转皆可。仿Weex的隐式意图如下:

public class TestModule extends WXModule{    @JSMethod(uiThread = false)    public void getParams(...){        Intent intent = new Intent(Intent.ACTION_VIEW);        intent.addCategory(Intent.CATEGORY_DEFAULT);        intent.addCategory("com.moon.android.intent.category.WEEX");        Activity activity = (Activity) mWXSDKInstance.getContext();        intent.setData(Uri.parse(param));        activity.startActivity(intent);    }}

当然记得要注册com.moon.android.intent.category.Weexcategory和对应的action

经试验,此方法可用,在此感谢我的同事耐心的陪我疯狂测试和疯狂修改(原本优雅的代码在测试中一点点的变成了test……),同时感谢各个交流群中集思广益,我时刻信奉一句话:不交流无进步!

0 0
原创粉丝点击