基于Weex的跨多端融合方案(三)
2019-03-23 本文已影响23人
Meteorwizard
概述
正常情况下,我们在native端是直接通过weex的bundleJS地址来加载weex页面的(通过WXSDKInstance的renderByUrl方法)。
public void renderByUrl(String pageName, final String url, Map<String, Object> options, final String jsonInitData, final WXRenderStrategy flag) {
renderByUrlInternal(pageName,url,options,jsonInitData,flag);
}
但是在做页面跳转的时候,我们往往是需要再带上一些业务参数的,此外,如果碰到Weex的页面有问题我们还需要考虑降级策略,一般是降级成H5页面。举个例子,我们在一个列表页请求了一个业务接口,接口中返回了列表中每个item项的跳转url,这个url上需要拼上常规的业务参数,最终传给Weex页面。当后台配置开启降级策略后,这个url需要直接跳转到H5页面。
Url与bundleJS的映射
因此我们需要维护一个Map来做好url与最终Weex页面的bundleJS之间的映射关系。当我们拿到url后,先从这个Map中找到对应的bundleJS,然后再执行跳转,并且带上从url中解析出来的参数。这些参数最终是会带在renderByUrl的jsonInitData参数中。
private static HashMap<String, String> getParams(String url) {
try {
Uri uri = Uri.parse(url);
HashMap<String, String> params = new HashMap<>();
Set<String> keys2 = uri.getQueryParameterNames();
for (String key : keys2) {
String value = uri.getQueryParameter(key);
if (TextUtils.isEmpty(value) || TextUtils.isEmpty(key)) {
continue;
}
params.put(key, value);
}
return params;
} catch (Exception ex) {
return new HashMap<>();
}
}
private String getParamsInitData() throws JSONException {
String initData = null;
if (mParams != null) {
JSONObject jsonObject = new JSONObject();
Set<Map.Entry<String, String>> entrySet = mParams.entrySet();
for (Map.Entry<String, String> entry : entrySet) {
if (!TextUtils.isEmpty(entry.getKey())) {
jsonObject.put(entry.getKey(), entry.getValue());
}
}
if (mExtraParams != null) {
Set<Map.Entry<String, String>> entries = mExtraParams.entrySet();
for (Map.Entry<String, String> entry : entries) {
if (!TextUtils.isEmpty(entry.getKey())) {
jsonObject.put(entry.getKey(), entry.getValue());
}
}
}
initData = jsonObject.toString();
}
return initData;
}
bundleJS加载逻辑
对于bundleJS一般来说会有两种加载方式:1. 本地资源包 2. 远程连接
考虑到用户体验,我们推荐是在app启动的时候预先将所有的bundleJS下载到本地,然后当需要打开相应页面的时候就可以直接从本地获取,只有在本地加载出错的时候才会去加载远程链接的bundleJS。
页面跳转
之前文章有提到过,多个Weex页面跳转我们目前使用的是多个容器间的跳转,说白了就是一个Weex页面就是一个Activity,页面的跳转就是Activity的跳转。于是我们就需要定义一个Bridge能力来做页面的跳转。
public class NavigatorModule extends WXNavigatorModule {
private static final String URL = "url";
public NavigatorModule() {
}
@JSMethod
public void push(String param, JSCallback callback) {
//跳转的代码
}
}