背景
為了保持三端統(tǒng)一的開發(fā)體驗,目前我們工程中用到的路由跳轉(zhuǎn)都是使用原生端封裝好的方法進行頁面跳轉(zhuǎn),比如點擊登錄 按鈕,在HTML或者weex當中會統(tǒng)一調(diào)用如下格式的代碼:
("ext.util.router",{
path: urlPath
},function (data) {
//data為原生回調(diào)js的參數(shù)
}
)
params當中的url是當前需要需要跳轉(zhuǎn)的頁面地址,我們采用scheme(weex/native)://pageUrl?params="xxx"的URI字符串來定義路由跳轉(zhuǎn)規(guī)則,scheme可以傳weex或者nativie,android原生端通過該標識來區(qū)分是跳轉(zhuǎn)到原生Activity還是WeexActivity頁面.
頁面間參數(shù)傳遞
有如下場景:列表list.js界面跳轉(zhuǎn)到詳情detal.js?id="666"
- 如何在詳情界面取到id的值?
android的原生代碼當中提供了renderByUrl的方法來渲染界面,同時傳遞了BUNDLE_URL的參數(shù):
protected void renderPageByURL(String url, String jsonInitData) {
CommonUtils.throwIfNull(mContainer, new RuntimeException("Can't render page, container is null"));
Map<String, Object> options = new HashMap<>();
options.put(WXSDKInstance.BUNDLE_URL, url);
mInstance.renderByUrl(
getPageName(),
url,
options,
jsonInitData,
WXRenderStrategy.APPEND_ASYNC);
}
這個url在js代碼中可以通過weex.config.bundleUrl獲取到,通過解析url,進行正則匹配和URI解碼,
就能夠截取到相應(yīng)的參數(shù)數(shù)據(jù),native ->weex(native)同理,weex頁面的正向傳參就此解決.
指定weex頁面返回
- 如何實現(xiàn)返回到指定頁面并反向傳值?
有如下場景:A頁面跳轉(zhuǎn)到B頁面,B再跳轉(zhuǎn)到C,C頁面操作完畢后返回A頁面,并且?guī)Щ亓艘恍﹨?shù):
WeexActivity是js的加載容器,啟動模式為standard標準模式,意味著每加載一個js文件,就在棧頂新建一個Activity,既然只有一個WeexActivity,那么就不能通過普通的Intent(context, WXPageActivity::class.java)跳轉(zhuǎn)到指定的類文件,目前android端采用了如下方案:
- 首先自定義一個WxManager用來管理WeexActivity的實例:
public class WxManager{
private static final WxManagerourInstance = new WxManager();
private static HashMap<String, Activity> activityHashMap = new HashMap<>();
public static WxManager getInstance() {
return ourInstance;
}
private WxManager() {
}
public void registerActivity(String path, Activity activity) {
if (activity != null && !TextUtils.isEmpty(path)) {
activityHashMap.put(path, activity);
}
}
}
在WeexActivity 的OnCreate方法中,把對應(yīng)的path和activity注冊到WxManager
- android原生端在收到weex發(fā)送的回退到指定頁面的事件后,調(diào)用方法進行比對,path不一致則銷毀當前Activity,直到回退到指定界面:
val activityList = ActivityUtils.getActivityList()
val returnActivity = WxManager.getInstance().getActivity(returnPath)
for (i in activityList.indices.reversed()) {
val activity = activityList[i]
if (activity == returnActivity) {
return
}
Intent().apply {
putExtra("refresh",refresh)
activity.setResult(Activity.RESULT_OK, this)
activity.finish()
}
}
回退到指定界面的問題解決了,那么該如何反向傳遞參數(shù)呢?android提供了startActivityForResult方法:
如果想在Activity中得到新打開Activity 關(guān)閉后返回的數(shù)據(jù),需要使用系統(tǒng)提供的startActivityForResult(Intent intent, int requestCode)方法打開新的Activity,新的Activity 關(guān)閉后會向前面的Activity傳回數(shù)據(jù),為了得到傳回的數(shù)據(jù),必須在前面的Activity中重寫onActivityResult(int requestCode, int resultCode, Intent data)方法。
因此我們在啟動WeexActivity 時默認調(diào)用startActivityForResult:
//啟動一個新的WeexActivity 頁面
public static void start(Context context, String url) {
Intent intent = new Intent(context, WXPageActivity.class);
intent.setData(Uri.parse(url));
if (context instanceof Activity) {
((Activity) context).startActivityForResult(intent, REQUEST_CODE);
} else {
context.startActivity(intent);
}
}
在OnActivityResult方法中進行參數(shù)接收:
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE) {
boolean needRefresh = data.getBooleanExtra("refresh", false);
if (needRefresh) {
refresh();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
refresh方法通過通過fireGlobalEventCallback把數(shù)據(jù)傳遞到weex頁面。
public void refresh() {
if (mInstance != null) {
Map<String, Object> params = new HashMap<>();
mInstance.fireGlobalEventCallback("weexRefreshData", params);
}
}
在weex頁面監(jiān)聽weexRefreshData事件并處理:
globalEvent.addEventListener('weexRefreshData', function(e) {
});
自此反向傳參實現(xiàn)完成.