Weex Android SDK源码分析

前言

最近开始试水Weex开发,使用这么长一段时间,感觉写Weex还是非常方便的。作为一个Android开发,免不了要追查一下weex的sdk源码。今天,就以Weex SDK for Android为例,分析SDK的

认识Weex SDK

源码https://github.com/alibaba/weex/tree/dev/android

整体分析下拉,按照js文件的渲染过程,绘制出了下面架构图:

sdk_framework

WEEX文件渲染过程

为了更加详细的说明整个渲染过程,我对源码进行了分析。并结合示例,进行了日志分析;比如,我们要开发如下一个简单的组件(红色方框内):
demo

那么,我们的wxc-title.we源码为:

<!-- wxc-title.we created by mochuan.zhb-->
<template>
    <div class="container">
        <image class="image" src="{
   {
   item.pic}}"></image>
        <text class="text">{
   {
   item.name}}</text>
    </div>
</template>

<style>
    .container {
        position: relative;
        flex-direction: row;
        width: 750px;
        height: 60px;
        align-items: center;
    }
    .image {
        margin-left: 100px;
        width: 45px;
        height: 45px;
    }
    .text {
        margin-left: 10px;
        font-size: 28px;
        color: #444444;
    }
</style>

<script>
    module.exports = {
        data: {
            item: {
                pic: '//img.alicdn.com/tfs/TB1AEcQNXXXXXX8XXXXXXXXXXXX-50-50.png',
                name: '当地玩乐'
            }
        },
        methods: {

        }
    }
</script>

上述.we文件经过weex编译之后,生成的js文件,经过格式化如下:

...
([function (module, exports) {
   
    module.exports = {
        "type": "div",
        "classList": [
            "container"
        ],
        "children": [
            {
                "type": "image",
                "classList": [
                    "image"
                ],
                "attr": {
                    "src": function () {
   
                        return this.item.pic
                    }
                }
            },
            {
                "type": "text",
                "classList": [
                    "text"
                ],
                "attr": {
                    "value": function () {
   
                        return this.item.name
                    }
                }
            }
        ]
    }
}, function (module, exports) {
   

    module.exports = {
        "container": {
            "position": "relative",
            "flexDirection": "row",
            "width": 750,
            "height": 60,
            "alignItems": "center"
        },
        "image": {
            "marginLeft": 100,
            "width": 45,
            "height": 45
        },
        "text": {
            "marginLeft": 10,
            "fontSize": 28,
            "color": "#444444"
        }
    }
}, function (module, exports) {
   
        module.exports = function (module, exports, __weex_require__) {
   
            'use strict';
            module.exports = {
                data: function () {
   
                    return {
                        item: {
                            pic: '//img.alicdn.com/tfs/TB1AEcQNXXXXXX8XXXXXXXXXXXX-50-50.png',
                            name: '当地玩乐'
                        }
                    }
                },
                methods: {}
            };
        }
    }
]);

上述分别使用了三个function,对template、style和script进行了封装;那么,这个文件是怎么被weex sdk执行并解析,最终生成结构化的View的呢?

渲染过程

时序图1:

从扫码开始,首先经历如下过程;依次经过readerPage,createInstance,一直到WXBridge的exeJs方法;也就是说,最终,Java通过调用native的exeJs方法,来执行js文件的。

https://img.alicdn.com/tps/TB1CKC.OFXXXXXkXpXXXXXXXXXX-2530-840.png

时序图2:

紧接着时序图1:执行到JNI层的Java_com_taobao_weex_bridge_WXBridge_execJS方法;

https://img.alicdn.com/tps/TB1K2uBOFXXXXbnaXXXXXXXXXXX-2374-1352.png

然后js通过native调用WXBridge的callNative方法,达到js调用Java代码的目的;
JNI层的部分代码如下:

jint Java_com_taobao_weex_bridge_WXBridge_execJS(JNIEnv *env, jobject this1, jstring jinstanceid,
                                                 jstring jnamespace, jstring jfunction,
                                                 jobjectArray jargs) {

    v8::HandleScope handleScope;
    v8::Isolate::Scope isolate_scope(globalIsolate);
    v8::Context::Scope ctx_scope(V8context);
    v8::TryCatch try_catch;
    int length = env->GetArrayLength(jargs);
    v8::Handle<v8::Value> obj[length];

    jclass jsObjectClazz = (env)->FindClass("com/taobao/weex/bridge/WXJSObject");
    for (int i = 0; i < length; i++) {
        jobject jArg = (env)->GetObjectArrayElement(jargs, i);

        jfieldID jTypeId = (env)->GetFieldID(jsObjectClazz, "type", "I");
        jint jTypeInt = env->GetIntField(jArg, jTypeId);

        jfieldID jDataId = (env)->GetFieldID(jsObjectClazz, "data", "Ljava/lang/Object;");
        jobject jDataObj = env->GetObjectField(jArg, jDataId);
        if (jTypeInt == 1) {
            jclass jDoubleClazz = (env)->FindClass("java/lang/Double");
            jmethodID jDoubleValueId = (env)->GetMethodID(jDoubleClazz, "doubleValue", "()D");
            jdouble jDoubleObj = (env)->CallDoubleMethod(jDataObj, jDoubleValueId);
            obj[i] = v8::Number::New((double) jDoubleObj);
            env->DeleteLocalRef(jDoubleClazz);
        } else if (jTypeInt == 2) {
            jstring jDataStr = (jstring) jDataObj;
            obj[i] = jString2V8String(env, jDataStr);
        } else if (jTypeInt == 3) {
            v8::Handle<v8::Value> jsonObj[1];
            v8::Handle<v8::Object> global = V8context->Global();
            json = v8::Handle<v8::Object>::Cast(global->Get(v8::String::New("JSON")));
            json_parse = v8::Handle<v8::Function>::Cast(json->Get(v8::String::New(
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值