WEEX 使用navigator跳转Android系统出现ActivityNotFoundException报错
最近在用 WEEX 做移动项目,出现在使用 navigator 的时候报ActivityNotFoundException
的错误,在网上没有找到很准确的答案,所以记录下来。
问题
在使用 weex 的 navigator 模块进行页面跳转的时候出现
ActivityNotFoundException
的异常如果安装了 weex 的 Playground APP,那么就会跳转到 Playground 中去显示 navigator 指向的页面。
navigator跳转:
navigator.push({ url: ServeAddress + Bundle, animated: 'true' }, event => { modal.toast({ message: '页面跳转' }) })
原因
查阅了一些资料后,突然明白了它的工作原理。
navigator 的跳转是一个 Android 的 startActivity
的过程,所打开的 Activity 就是写有拦截器的 Activity 。而拦截器是跨应用的,所以我们在使用 navigator 模块跳转的时候会跳转到 Playground 的 Activity 中去!而且当一个手机中有多个带有相同拦截器的 Activity 的时候,Android 系统还会让我们去选择进入到哪个 Activity 中。
所谓的拦截器
就是将一段标签代码放到 AndroidManifest 的 <activity>
标签下。下面是 Playground 的AndroidManifest中拦截器的写法。:
<activity android:name=".WXPageActivity" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="com.taobao.android.intent.action.WEEX"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="com.taobao.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>
解决方案
参照 Playground,创建一个带有拦截器的 Activity。
比如 ActivityA
是用来渲染当前 weex 页面的,在 weex 页面中使用 navigator
来做页面跳转,如果你在 ActivityA
中添加拦截器,那么 navigator
会再打开一个 ActivityA
,这就是有些网友说的为什么总是打开重复的页面的原因。
<activity android:name=".ActivityA"> <intent-filter> <action android:name="com.taobao.android.intent.action.WEEX" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="com.taobao.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>
第一种方法:ActivityA
的拦截器不变,继续跳转到 ActivityA
页面。但是在 ActivityA
中去获取 Intent
数据,看看是否为 navigator
跳转过来的页面,如果是则加载不同页面。navigator
的跳转 url
获取方式为 getIntent().getData().toString();
String RenderPageUrl = SharedPreferencesUtil.getSP(context, Ips.KEY, "ERROR"); LogUtil.e(RenderPageUrl); if (getIntent().getData() != null) { String navUrl = getIntent().getData().toString(); if (null != navUrl) { LogUtil.e(navUrl); RenderPageUrl = navUrl; } else { LogUtil.e("a is null"); } } else { LogUtil.e("get data is null"); } Map<String, Object> options = new HashMap<>(); options.put(WXSDKInstance.BUNDLE_URL, RenderPageUrl); mWXSDKInstance.renderByUrl("WXSample", RenderPageUrl, options, null, WXRenderStrategy.APPEND_ONCE);
方法二:新建一个ActivityB,专门用来显示navigator跳转的页面。页面功能为通过Intent获取url,然后进行渲染。
通过Intent方法与方法一相同。
渲染页面的Activity的写法可以参照这里。
呃……其实两个方法是一回事啦。只不过我不喜欢多写一个Activity来承载新页面~所以会选择第一个方法。
一开始找不到问题解决方案还挺绝望的,后来想想Playground可以实现,于是就去看了看Playground的源码,再配合上网上有一些零星的解决方案,才搞定。所以呢,看源码还是很能解决问题的~