Android端自定義Weex路由跳轉(zhuǎn)

背景

為了保持三端統(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)完成.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容