Weex专栏

[转]Weex页面间的跳转及Android端多应用选择窗口的处理

2019-07-29  本文已影响21人  安卓搬砖小曾

一、前言

二、页面跳转

<script>
var navigator = weex.requireModule('navigator')
var modal = weex.requireModule('modal')
  export default {
    methods: {
      //跳转,进入
      jump (event) {
        console.log('will jump')
        navigator.push({
          url: 'http://dotwe.org/raw/dist/519962541fcf6acd911986357ad9c2ed.js',
          animated: "true"
        }, event => {
          modal.toast({ message: '页面跳转callback: ' + event })
        })
      },
        // 返回,退出
        back(event) {
        navigator.pop({ animated: 'true' }, event => {
          modal.toast({ message: '页面返回 callback: ' + event })
        })
      }
    }
  };
</script>

Web端


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

Android端

        <activity
            android:name="com.weex.app.SplashActivity"
            ...
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            ...
        </activity>

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

        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();

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

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

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

这个时候,我们知道了Android端的跳转uri制定规则,是不是就可以解决并完成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);
        ...                 
    }

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

        <activity
            android:name="com.weex.app.WXPageActivity"
              ...
            <intent-filter tools:ignore="AppLinkUrlError">
                <action android:name="com.taobao.android.intent.action.WEEX" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="com.moon.android.intent.category.WEEX" />
                <action android:name="android.intent.action.VIEW" />
                <data android:scheme="http" />
                <data android:scheme="https" />
                <data android:scheme="file" />
                <data android:scheme="wxpage" />
            </intent-filter>
             ...
        </activity>

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

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

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

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

更改为:

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

即可。

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


    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);
        ...                 
    }

只是设置了Category为:com.taobao.android.intent.category.WEEX,这样,当我们在AndroidManifest.xml文件中的WXPageActivity添加:

   <category android:name="com.taobao.android.intent.category.WEEX" />

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

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、在WXApplication中注册TestModule,代码如下所示:

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

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

<script>
var navigatorTest = weex.requireModule('TestModule')
  export default {
    methods: {
      register(event) {
          navigatorTest.push('file://assets/Register.js')
      }
    }
  };
</script>

参考博文:

https://blog.csdn.net/violetjack0808/article/details/74390249
https://blog.csdn.net/byxyrq/article/details/71629209
https://blog.csdn.net/xiaoyu940601/article/details/55509907

文章来源:https://www.jianshu.com/p/572199f9b838

上一篇下一篇

猜你喜欢

热点阅读