Bootstrap

Weex开发:页面跳转以及Android端多应用选择窗口的处理

前言

在使用开发项目的过程中,官网上面实现页面跳转的方式在端是没问题的,但是在、两端上面就会有问题,本文主要是将探索的过程记录一下。

页面跳转

的页面跳转,主要是通过使用  来实现,但是三端使用的过程中,因为的规则其实并不统一,所以需要根据不同的平台,做不同的跳转处理。在浏览器里,我们可以通过前进或者回退按钮来切换页面,的  模块就是用来实现类似的效果,除了前进、回退功能,该模块还允许我们指定在切换页面的时候是否应用动画效果,使用方式如下代码所示:

Web端

端其实最好处理,只需要将路径设置为目标vue文件的文件名,再加上.html即可,比如从登录页面跳转到注册页面,代码可以这样写,如下所示:

    register(event) {
      navigator.push(
        {
          url: 'Register.html',
          animated: 'true'
        },
        event => {
          modal.toast({
            message: 'callback:' + event
          })
        }
      )
    }

Android端

端的跳转方案,官方文档并没有详细说明,对于新人来说,根本就无从下手。首先,我们查看端的源码,可以发现,是用于实现闪屏页的,在文件中,有如下设置:

        
                
                
            
            ...
        

在闪屏页旋转动画结束后,跳转到了,代码如下所示:

        Intent intent = new Intent(SplashActivity.this, WXPageActivity.class);
        Uri data = getIntent().getData();
        if (data != null) {
          intent.setData(data);
        }
        intent.putExtra("from", "splash");
        startActivity(intent);
        finish();

很明显,就是代理所有页面的渲染的。 

在中,我们运行的官方,可以发现项目在闪屏页结束后,跳转到的页面,也就是如下图所示:

 

这个页面的其实就是,源码如下所示:

       	if (mUri == null) {
            mUri = Uri.parse(AppConfig.getLaunchUrl());
        }

由此可以得出,的跳转是以开头的路径,而且打包的文件是存放在端代码的文件夹下。 

这个时候,我们知道了端的跳转制定规则,是不是就可以解决并完成端的页面跳转功能了?其实不是。 

在上使用  时,端需要做的事情是注册,具体情况可以查看sdk源码:类。

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

因此,我们对能够加载页面的需要在中进行清单文件的注册,使之能够响应隐式意图,所以我们需要在中加入如下代码:

        
                
                
                
                
                
                
                
                
            
             ...
        

接着,我们需要在中看到如下代码:

        Intent intent = getIntent();
        Uri uri = intent.getData();
        String from = intent.getStringExtra("from");
        mFromSplash = "splash".equals(from);

可知,就是所传入的文件路径地址,也就是说,我们要新增判断,只要将即可实现这个页面在里的渲染,为了识别传入的文件路径地址,并且能够处理启动页的逻辑,将中的代码:

        if (mUri == null) {
            mUri = Uri.parse(AppConfig.getLaunchUrl());
        }

更改为:

        if (mUri == null) {
            if (uri.toString().startsWith("file:")) {
                mUri = uri;
            } else {
                mUri = Uri.parse(AppConfig.getLaunchUrl());
            }
        }

至此,使用时实现了端页面跳转的功能,比如从登录页面跳转到注册页面,代码可以这样写,如下所示:

    register(event) {
      navigator.push(
        {
          url: 'file://assets/Register.js',
          animated: 'true'
        },
        event => {
          modal.toast({
            message: 'callback:' + event
          })
        }
      )
    }

Android 7.0 以上,使用以上方案Weex页面无法成功跳转的问题

因为从开始,一个应用提供自身文件给其他应用使用时,如果给出一个格式的的话,应用会抛出异常,这是由于认为目标可能不具有文件权限,会造成潜在的安全问题,所以让这一行为快速失败。解决方案是,只需在端代码文件的方法中加上如下代码即可:

    //Android 5.0 6.0不会出现问题,但是
    //Android 7.0以上,使用file:///会失败,通过这个判断去掉限制。
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
      StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
      StrictMode.setVmPolicy(builder.build());
    }

Android端多应用选择窗口的处理

private final static String WEEX = "com.taobao.android.intent.category.WEEX";

    @JSMethod(uiThread = true)
    public void push(String param, JSCallback callback) {
        ...
     Intent intent = new Intent(Intent.ACTION_VIEW, builder.build());
     intent.addCategory(WEEX);
     intent.putExtra(INSTANCE_ID, mWXSDKInstance.getInstanceId());
     mWXSDKInstance.getContext().startActivity(intent);
        ...                 
    }

只是设置了为:,这样,当我们在文件中的添加:

   

时,是可以完成页面跳转功能的,只是这是官方默认的过滤规则,也就是意味着,如果手机安装多个开发的应用程序,在页面跳转的时候,就会出现多个应用响应隐式意图,然后系统就会出现多应用选择窗口。所以这里,将更改为:,使之唯一,也就是,只能响应本应用程序中的。

1.新建类,代码如下所示:

public class TestModule extends WXModule {
    @JSMethod(uiThread = false)
    public void push(String param) {
        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);
    }
}

2.在中注册,代码如下所示:

WXSDKEngine.registerModule("TestModule", TestModule.class);

3.在文件中使用,代码如下所示:

写在最后

接触快两年了,参与开发了公司里的两个项目,总的来说,跨平台相比原生开发,在效率方面提升确实很明显,很多样式一两行代码就可以了,但如果是使用原生来开发,光写都很费时间了,当然也有不足之处,就是在与各端交互的过程中,需要兼容,所以很容易出现各种问题,比如本文提到的页面跳转,就是一个很棘手的问题,至少对我来说是如此,因此,也是想要将一些心得记录下来,也算是接触以来,给自己留一点念想,后续不打算投入精力到方面,而是,从18年知道,就很看好,现在发展迅速,越发壮大了。