Weex has launched a commonly used order management page on the App of Shangzhuang’s Talent store. So far, no problem has been found on Android, and the rendering time is between 100-300ms.

As an Android development, this article will first record the access process from the perspective of Android, hoping to provide some help for the students who are not connected to weeX more convenient and time-saving. It will involve preloading, degradation, hot update, and dynamic configuration of new pages in the case of app not updated, and so on. I hope to communicate with you. For the front end, see my colleague’s Introduction to WEEX Practice (Front End Perspective).

I. Android access process


Module, component, IWXImgLoaderAdapter, IWXHttpAdapter rewrite, etc., have been well examples in playgroup and WeexTeam.

Gradle dependencies

The compile 'com. Taobao. Android: weex_sdk: 0.8.0.2' compile 'com. Android. Support: support - v4:24.0.0' compile 'com. Android. Support: appcompat - v7:24.0.0' compile 'com. Android. Support: recyclerview - v7:24.0.0' compile 'com. Squareup. Okhttp: okhttp: 2.3.0' compile 'com. Squareup. Okhttp: okhttp - ws: 2.3.0' compile 'com. Alibaba: fastjson: 1.2.8' // Support debugging dependencies, The compile a reference https://github.com/weexteam/weex-devtools-android/blob/master/README-zh.md 'com. Taobao. Android: weex_inspector: 0.0.8.5' compile 'com. Google. Code. Findbugs: jsr305:2.0.1' compile 'com. Taobao. Android: weex_inspector: 0.0.8.5'Copy the code

2. Create a WEEX Module

Create a separate WeeX Module on the original Project. The code structure is as follows:

3. Initialize the WEEX

Init (WeexManager) init (application onCreate)

Public void init(Application Application) {public void init(Application Application) {if (! ConfigManager.getBoolean(CONFIG_WEEX_ENABLE, true)) { return; } context = application.getApplicationContext(); weexDir = context.getDir(WEEX_MODULE, Context.MODE_PRIVATE); WXSDKEngine.initialize(application, new InitConfig.Builder() .setImgAdapter(new FrescoImageAdapter()) .setUtAdapter(new UserTrackAdapter()) .setStorageAdapter(new StorageAdapter()) .setHttpAdapter(new OkHttpAdapter()) .build()); SetConfig (shstoragemanager.get (WEEX_MODULE, WEEX_CONFIG, "")); //SHStorageManager is a storage module. Try {/ / page. Some common interface WXSDKEngine registerModule (" shopBase, "ShopModule. Class); / / is primarily a label jump WXSDKEngine registerModule (" event ", WXEventModule. Class); / / modal dialog box WXSDKEngine. RegisterModule (" shopModal, "ModalModule. Class); WXSDKEngine.registerComponent("image", FrescoImageComponent.class); } catch (WXException e) { LogUtils.e(e); // Error collection module}}Copy the code

1) Considering that it is the first time to access WEEX, I am a little worried about compatibility problems in case of crash and other uncertain factors, so I made a switch here. In fact, it’s best to have a switch every time you plug in a new SDK to avoid instability due to uncertainty.

2) weexDir is the download and storage path of JS. In order to speed up the page opening time, JS will be preloaded locally

3) THE SDK only calls the openURL interface of “event” for the processing of tag A, but does not register “event”. So you need to implement the WXEventModule yourself and register it.

4) Refer to WXModalUIModule in SDK for implementation of ModalModule

5) FrescoImageAdapter and FrescoImageComponent are implemented in weexTeam, which supports webP and compression. Supports links without protocols (Ignoring protocols allows the browser to automatically select the protocol to use according to the page’s HTTP or HTTPS, thus avoiding the problem that a website can still access HTTP resources when it changes to HTTPS.)

6) OkHttpAdapter implementation reference github zjutkz students implementation OkHttpAdapter, thanks, after rewriting, support no protocol link

7) ShopModule is a custom Module that defines some common interfaces, such as setting whether the title bar is displayed and the title of the title bar; Close the current page, sharing, error log collection, etc.

4. Create a unified WEEX page

In the future, the page may be embedded in other activities, or put weex rendering into the new WeexFragment. Then create a New WeexActivity to reference the WeexFragment. All weeX renderings of individual pages use this activity, while non-individual pages use weexFragment, so you don’t need to re-register the activity when adding new pages. The unified weeX processing logic facilitates management and dynamic configuration. Jump to WeexActivity via the unified Jump protocol, passing in two parameters url and h5 via the intent.

 
           showjoyshop://page.sh/weex
             Copy the code

Url: js links, can be a local store address/sdcard/com. Showjoy. Shop/weex/order. Js, can also be online links to https://xxxxx/0.4.3/order.js

H5: A link to the H5 page used to downgrade, to which it will jump when rendering fails

5. Start rendering JS, demote to H5 after failure

First, instantiate WXSDKInstance

 
            wxInstance = new WXSDKInstance(activity);
wxInstance.registerRenderListener(this);
wxInstance.onActivityCreate();
registerBroadcastReceiver();
                            Copy the code

1) The current class implements the interface IWXRenderListener, which can be implemented by referring to the AbsWeexActivity in WeexTeam

2) The registered broadcast is DefaultBroadcastReceiver. You can refer to the AbsWeexActivity implementation in WeexTeam

Then a little bit about rendering, support for local JS as well as online JS

 
            if (url.startsWith("http")) {
    wxInstance.renderByUrl(
            getPageName(),
            url,
            options,
            jsonInitData,
            CommonUtils.getDisplayWidth(activity),
            CommonUtils.getDisplayHeight(activity),
            WXRenderStrategy.APPEND_ASYNC);
 
}else {
 
    new Thread(new Runnable() {
        @Override
        public void run() {
            String file = WeexUtils.readFile(url);
            handler.sendMessage(handler.obtainMessage(LOAD_LOCAL_FILE, file));
        }
    }).start();
}
             Copy the code

GetPageName () is custom, getDisplayWidth and getDisplayHeight get the screen width and height.

When the local storage address is passed in, the file is first read, and then the same Handler renders in the UI thread, as follows:

 
            if (activity.getLifeState() != LifeState.DESTORY ) {
    if (wxInstance != null) {
        String content = (String) msg.obj;
        if (TextUtils.isEmpty(content)) {
            SHJump.openUrl(activity, h5Url);
            finishActivity();
        }else {
            wxInstance.render((String) msg.obj, null, null);
        }
    }
}
             Copy the code

Here getLifeState() is our own BaseActivity implementation, and you can judge for yourself. Both SHJump and finishActivity are their own implementations.

Rendering callback implementation, according to the need to process, after the successful rendering hide loading, view creation add view. Demote jumps to H5 when rendering exception occurs. Such as:

 
            @Override
public void onViewCreated(WXSDKInstance instance, View view) {
    //viewMap.put(weexJsUrl, view);
    addWeexView(view);
}
@Override
public void onRenderSuccess(WXSDKInstance instance, int width, int height) {
    toHideLoading();
}
@Override
public void onRefreshSuccess(WXSDKInstance instance, int width, int height) {
    toHideLoading();
}
@Override
public void onException(WXSDKInstance instance, String errCode, String msg) {
    LogUtils.e("weex exception:", errCode, msg);
    SHJump.openUrlForce(activity, h5Url);
    finishActivity();
}

             Copy the code

6. Multiple JS renderings on the same page

To implement the TAB as shown, we initially used the Tabbar component in a. We file, but later found that it was not good enough for Android devices. Then I made two tabs into two pages, generating two JS files. First render “Myord.js” to generate the following interface. Then click “order from this store” and call the interface loadPage in the custom Module with the parameter H5 link. H5 directly redirects to the loadPage interface, while iOS and Android use the H5 link to find the corresponding JS from the WEEX redirect configuration and re-render the display. Here are some specific explanations:

1) Map<String, WXSDKInstance> wxsdkInstanceMap Define Map<String, View> viewMap to store views rendered by different JS. The reason for storing multiple WxsdkInstances is that WXSDKInstance cannot be rendered repeatedly, and when the WXSDKInstance is destory, the contents of the previously rendered view will be emptied. Note that when destory the page, destory all wxsdkinstances.

2) Key in viewMap corresponds to js of the page. Click TAB to switch the page, if the corresponding JS has been rendered, then directly take out the View to display.

3) The weeX forward configuration mentioned above is described in the following weeX forward rules.

Second, App jump rule weeX support scheme design


The jump rule is shown as follows. If you can’t see it clearly, you can zoom in and view it on the new page. The following two configuration parameters are mainly introduced:

InterceptUrlList 1) parameters can be configured dynamically to intercept the h5 links, then generate a unified jump address showjoyshop: / / page. Sh/order

The following is an example:

 
            [
    {
        "page":"order",
        "url":"https://dshdjshjbx"
    },
    {
        "page":"detail",
        "url":"https://dsdsds"
    }
]
             Copy the code

Page: indicates the unified forward protocol, that is, the same as the page in the WEEX configuration.

Url: A regular expression for a link to match

V: Supported by the latest version

2) Then use order to find the corresponding JS information in the parameter weexPages, and render.

The following is an example:

[{" page ":" order ", "url" : "https://dshdjshjbx.js", "md5" : "323827382 huwhdjshdjs", "h5" : "http://dsds.html" "v" : "1.5.0"}, {" page ":" detail ", "url" : "https://dsdsds.js", "md5" : "323827382 huwhdjshdjs", "h5" : "http://dsds.html" "v" : "1.5.0}"]Copy the code

Page: indicates the path of the unified forward

Url: the JS to render,

Md5: the MD5 value of the JS file is used for verification.

H5: Demote scheme after rendering failure,

V: indicates the lowest supported version number


This achieves the purpose of dynamic interception and dynamic on-line WEEX.

Third, JS preloading scheme


In order to speed up the weeX open time, js will be preloaded, here introduces the implementation of JS preloading.

1) After updating the configuration file each time, traverse to check whether there is an MD5 consistent page_XXx. js file. If not, update it.

2) After downloading, save the file in xxx.js format to verify MD5

  • If so, record the last modification time of the file;

  • If not, delete the downloaded file, download it again, and repeat the verification process.

3) Support the unified jump protocol. Page corresponds to the page in the unified jump protocol of the current APP terminal. When necessary, the original Native page can be replaced to solve the problem that the errors of the native page cannot be repaired in time. If loading fails, open the H5 page.

4) Every time the specified page is opened, check whether there is a corresponding page file in the local first, and then check whether the last modification time is consistent with the record

  • Consistent load

  • If not, use the line URL.

4. Problems encountered and solutions


Problem a: Public void onException(WXSDKInstance instance, String errCode, String MSG) ErrCode returns wx_create_instance_error, MSG returns createInstance Fail!

Workaround: After unpacking apK, you find that you have compiled a package that supports five ABI’s. However, libweexv8.so is only available in Armeabi and x86 and lacks support for the other three ABI’s, so applications running on devices with arm64-V8A, X86_64, and Armeabi-v7A as the preferred ABI will fail to load. The arm64-V8A, ArmeabI-V7A, and X86_64 ABI are not required to be supported. So we just need to remove support for x86, ARM64-V8A, and x86_64. Add the following content to the android defaultConfig in build.gradle of the main module:

 
           defaultConfig {  
    ndk {  
        abiFilters "armeabi", "x86"  
    }  
}


                 Copy the code

Error 2: A resolution error occurs when the OkHttpAdapter calls onHttpFinish. The log is as follows:

 
            com.alibaba.fastjson.JSONException: syntax error, pos 2
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1300)
    at com.alibaba.fastjson.parser.DefaultJSONParser.parse(DefaultJSONParser.java:1210)
    at com.alibaba.fastjson.JSON.parse(JSON.java:109)
    at com.alibaba.fastjson.JSON.parse(JSON.java:100)
    at com.taobao.weex.http.WXStreamModule.parseJson(WXStreamModule.java:378)
    at com.taobao.weex.http.WXStreamModule$2.onResponse(WXStreamModule.java:365)
    at com.taobao.weex.http.WXStreamModule$StreamHttpListener.onHttpFinish(WXStreamModule.java:523)
    at com.showjoy.weex.commons.adapter.OkHttpAdapter$6.onResponse(OkHttpAdapter.java:161)
    at okhttp3.RealCall$AsyncCall.execute(RealCall.java:133)
    at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
                            Copy the code

Solution: Catch exception

try { if (null ! = listener) { listener.onHttpFinish(wxResponse); } } catch (Exception e) { LogUtils.e(e); }Copy the code

Problem 3: Switching between online and offline environments.

Solution: Use relative address for link and request address in. We file, h5 page will automatically select the domain name used by the page, and do block processing on iOS and Android, add corresponding domain name according to the current environment.


Reference links:

github.com/weexteam/

weex-project.io/doc/

Github.com/alibaba/wee…

To play to admire


Your support will encourage us to continue to create!

WeChat pay
Alipay

Scan the QR code with wechat to tip

Scan the QR code with Alipay