Weex基于Android Studio从开发环境搭建到运行

Weex之路——引路篇
Weex的迭代目前来说已经经过了很多版本,官方的文档已经过时,而且文档本身写的也很简陋,按官方文档很难把APP跑起来。经过多次趟坑后,决定把自己的经历写下来,给当前准备着手Weex开发的人一点参考:

Android Studio版本 3.1
Node.js版本 v8.9.3
Npm版本 5.5.1
JDK版本 1.7
Android SDK Compile Sdk Version 23
Android SDK Build Tools Version 25.0.0
Gradle version 4.1
Android Plugin version 2.3.3
环境安装及配置
JDK、Android SDK的安装及环境变量配置不赘述
Node.js安装: 
安装完成后检查 

安装 weex-toolkit。
npm install weex-toolkit -g
1
创建Weex项目
找一个目录作为Weex项目的工作空间(workspace),在命令行执行如下代码,创建weex项目:

weex create awesome-app
1
项目名就是awesome-app 


如果有小白不知道命令行执行是什么意思的,看下图: 


运行Weex项目
在命令行执行:

cd awesome-app
npm install
npm start
1
2
3
上面三个命令的意思分别是:进入awesome-app目录,安装依赖,启动。 
所以后续需要运行weex工程,只需要在awesome-app目录下的命令行模式,运行npm start就能启动项目。 
如图,我对代码做了一点修改 

启动完成后会自动在浏览器中打开index界面,效果如下 


至此,weex项目在web环境的搭建及运行就完成了。

下面开始Android开发所需的配置。

创建Android项目
怎么将Weex最终做出APP能运行起来最主要的工作就是这里了
Step 1
在Android Studio中新建一个空白的Android项目,配置包名。我的应用包名是:cn.com.acoe.weexapp.app
Step2
配置build.gradle
apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    defaultConfig {
        applicationId "cn.com.acoe.weexapp.app"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    buildToolsVersion '25.0.0'
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
    productFlavors {
    }
}

dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    compile 'com.android.support:appcompat-v7:23.1.1'
    compile 'com.android.support:recyclerview-v7:23.1.1'
    compile 'com.alibaba:fastjson:1.1.46.android'
    compile 'com.taobao.android:weex_sdk:0.18.0@aar'

    compile 'com.squareup.okhttp:okhttp:2.3.0'
    compile 'com.squareup.okhttp:okhttp-ws:2.3.0'
    compile 'com.squareup.okio:okio:1.0.1'
    compile 'com.github.bumptech.glide:glide:3.7.0'


}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
因为示例中有图片的显示,所以除了官方文档给出的例子中依赖的几个包以外,我还引入了glide用于图片加载。okhttp是用来做网络请求的,所以我也引入了相关依赖。

Step 3
创建图片加载的Adapter
package com.app.weexapp.util;

import android.widget.ImageView;

import com.bumptech.glide.Glide;
import com.taobao.weex.adapter.IWXImgLoaderAdapter;
import com.taobao.weex.common.WXImageStrategy;
import com.taobao.weex.dom.WXImageQuality;

public class ImageAdapter implements IWXImgLoaderAdapter {
    @Override
    public void setImage(String url, ImageView imageView, WXImageQuality wxImageQuality, WXImageStrategy wxImageStrategy) {
        Glide.with(imageView.getContext()).load(url).into(imageView);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Step 4
创建Application,每个Android项目都少不了的步骤。
package com.app.weexapp.app;

import android.app.Application;
import android.util.Log;

import com.app.weexapp.util.ImageAdapter;
import com.taobao.weex.InitConfig;
import com.taobao.weex.WXSDKEngine;

/**
 * Application
 * Created by Acoe on 2018/4/4.
 */

public class WeexApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        InitConfig.Builder builder = new InitConfig.Builder();
        builder.setImgAdapter(new ImageAdapter());
        InitConfig config = builder.build();
        WXSDKEngine.initialize(this, config);
        Log.i("Application", "WXSDKEngine.isInitialized: " + WXSDKEngine.isInitialized());
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Step 5
创建Activity,来显示weex项目中编写的界面
package com.app.weexapp.ui;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;

import com.taobao.weex.IWXRenderListener;
import com.taobao.weex.WXSDKEngine;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.common.WXRenderStrategy;
import com.taobao.weex.utils.WXFileUtils;

import cn.com.acoe.weexapp.app.R;


/**
 * Created by Acoe on 2018/4/4.
 */

public class MainActivity extends AppCompatActivity {
    private WXSDKInstance mWXSDKInstance;
    private FrameLayout mContainer;
    private Handler mHandler;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mContainer = (FrameLayout) findViewById(R.id.container);

        mWXSDKInstance = new WXSDKInstance(this);
        mWXSDKInstance.onActivityCreate();
        mWXSDKInstance.registerRenderListener(new IWXRenderListener() {
            @Override
            public void onViewCreated(WXSDKInstance wxsdkInstance, View view) {
                if (mContainer != null) {
                    mContainer.addView(view);
                }
            }

            @Override
            public void onRenderSuccess(WXSDKInstance wxsdkInstance, int i, int i1) {
            }

            @Override
            public void onRefreshSuccess(WXSDKInstance wxsdkInstance, int i, int i1) {
            }

            @Override
            public void onException(WXSDKInstance wxsdkInstance, String s, String s1) {
            }
        });


        // 在渲染前先要保证WXSDKEngine已经完成了初始化
        if (WXSDKEngine.isInitialized()) {
          startRender();
        } else {
            mHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    if (msg.what == 0) {
                        Log.i("Main", "WXSDKEngine.isInitialized: " + WXSDKEngine.isInitialized());
                        if (WXSDKEngine.isInitialized()) {
                            startRender();
                        } else {
                            msg = mHandler.obtainMessage(0);
                            mHandler.sendMessageDelayed(msg, 100);
                        }
                    }
                }
            };
            Message msg = mHandler.obtainMessage(0);
            mHandler.sendMessageDelayed(msg, 100);
        }
        Log.i("Main", "onCreate over");

    }

    /**
     * 开始执行渲染
     */
    private void startRender() {
        mWXSDKInstance.render("Main", WXFileUtils.loadAsset("app.js", this),
                null, null, WXRenderStrategy.APPEND_ASYNC);
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (mWXSDKInstance != null) {
            mWXSDKInstance.onActivityResume();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if(mWXSDKInstance != null) {
            mWXSDKInstance.onActivityPause();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        if(mWXSDKInstance != null) {
            mWXSDKInstance.onActivityStop();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(mWXSDKInstance != null) {
            mWXSDKInstance.onActivityDestroy();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
布局文件的代码,activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></FrameLayout>

</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
如果有看过其他的weex介绍的文章,或者看过官网的文章,可以发现我的Activity代码有一点不一样的地方,就是在WXSDKInstance.render()执行weex界面渲染之前判断了WXSDKEngine是否有初始化完成。 
因为我在没有加这个判断及相应的处理之前,weex在浏览器里显示的那个界面一直渲染不出来,但是在debug一步一步找原因的过程中,发现在渲染之前断点多停留一会儿,界面最终就渲染出来了。 
而且日志中也出现多条JsFramework没有初始化的提示,于是就怀疑是在MainActivity进行界面渲染的时候WXSDKEngine应该还没有初始化成功,导致渲染失败。 
最终加上了确保WXSDKEngine初始化成功后再进行渲染,解决了问题。 
这个坑网上真是找不到一丁点资料,weex的相关文章还是太少,有深入了解的人也应该还是不多。

Step 5
AndroidMainfest.xml中配置好Application和Activity
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.com.acoe.weexapp.app">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:name="com.app.weexapp.app.WeexApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.app.weexapp.ui.MainActivity"
            android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
Step 6
将weex项目编译成js文件,拷贝到Android工程的assets目录下 
在之前创建的awesome-project目录,进入命令行模式,执行weex build android可以在当前目录的dist文件夹中编译出js文件。其实在启动weex项目的时候js文件也会生成好。 
拷贝好后(我这里是重命名成了app.js),我的Android主要目录结构如下


然后执行运行即可,下面是运行结果。 


至此从搭建环境到运行,整个流程就结束了。有什么不祥尽的地方敬请留言我会进行补充的。

最终感受
虽然Weex官方提出的“一次编写,处处运行”可以说是做到了,但是原生的工作量确实还是不少。其实如果阿里把Weex专门运营成一个API产品,前景应该还是非常好的,类似于国内DCloud、ACloud做的那样,底层封装好,开发者只关注于前端怎么实现,与底层的交互全是API厂商封装好的那样。但是阿里似乎不太可能有这样子的做法,但是给混合开发开创了一种高体验的途径,这点相信会给很多人带来启示。反正就目前而言,个人觉得不是一个很好的混合开发解决方案,仍然还有很多路要走。

github地址:https://github.com/Acoee/WeexApp.git

参考文档 
[1]: 官方手册 http://weex.apache.org/cn/guide/


转载:https://blog.csdn.net/zhuyb829/article/details/80003962 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值