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

在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……),同时感谢各个交流群中集思广益,我时刻信奉一句话:不交流无进步!

发布了23 篇原创文章 · 获赞 10 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/byxyrq/article/details/71629209
今日推荐