Weex总结之Android Weex工程搭建趟坑

简介: >目前虾米也打算接入Weex,内网上看似很多的基础教程,但根据讲解一步步做下来却一直无法实现效果。仔细看资料,才了解究竟是为什么,把自己的心得记录下来方便后来者。 今天要完成的效果就是使用Android工程来渲染下面的效果: ![blog1](http://img3.tbcdn.cn/L1/461/1/09c2f48df4a244bc707b8bfdfa0a545c334b00ab)

目前虾米也打算接入Weex,内网上看似很多的基础教程,但根据讲解一步步做下来却一直无法实现效果。仔细看资料,才了解究竟是为什么,把自己的心得记录下来方便后来者。

今天要完成的效果就是使用Android工程来渲染下面的效果:
blog1

一、基本释义

首先解释几个概念,方便大家有个整体了解

1、DSL与we文件

在有些文章中会提到 Weex DSL或者DSL,那么这个DSL究竟是个什么鬼呢?
DSL的全称是领域特定语言,是针对特定问题领域的编程语言,而非通用语言。所以Weex DSL也就是指针对Weex 所缩写的一套语言。
而利用Weex DSL语言所写的程序,保存时的格式就是我们常见的.we后缀格式。

2、we文件与js文件

在Android代码中,无法直接加载.we文件的,但是可以加载.js文件的,所以我们需要把.we文件转换成.js文件,Weex给我们提供了一个工具weex-toolkit
首先,我们需要利用nmp在命令行安装它:

npm install -g weex-toolkit

在安装完以后,在命令行,只输入weex,如果出现下面Help界面,就说明安装成功了
blog2
下面就是使用weex-toolkit转换we文件了

cd XXXX 
weex tech_list.we 

(tech_list.we文件在底部源码工程根目录下)
上面总共两句话,首先,将当前工作路径切换到we文件所在的目录,如果不切,则需要指定we文件所在的绝对路径。
然后直接使用weex命令转换即可
在输入命令以后,首先会直接打开一个网页显示这个we文件的渲染效果:
blog3
然后在tech_list.we文件所在的文件夹下,会产生一个文件夹weex_temp,这个文件夹是就浏览器中所显示的内容的源文件,其中有一个跟tech_list.we所对应的tech_list.js文件,它就是转换后的js文件,我们在Android工程中所使用的就是它!
blog4
在拿到tech_list.js以后,我们就开始搭Android工程了;

有关weex命令的更多用法,请参考《Transform Code into Js Bundle》

二、搭建Android Weex工程

这篇文章不基于源码构建,本篇文章的宗旨是教大家先跑起来……在跑起来以后再引入源码构建就好办了。

1、新建项目

(1)、新建gradle项目,Minimum SDK不得低于14;(低于14,Weex不支持)
blog5
(2)、配置gradle
在工程根目录下build.gradle文件中,加入阿里仓库,以便引入远程weex包:

allprojects {
    repositories {
        jcenter()
        maven{
            url "http://mvnrepo.alibaba-inc.com/mvn/repository"
        }
    }
}

文件位置如图:
blog6
(3)、添加依赖
在app项目中的build.gradle文件中,添加项目依赖:

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.4.0'
    compile 'com.taobao.android:weex_sdk:0.5.1' //添加SDK library依赖
    compile 'com.android.support:recyclerview-v7:23.3.0'
    compile 'com.alibaba:fastjson:1.1.45'
    compile 'com.squareup.picasso:picasso:2.5.2'
}

其中除了最后一个picasso依赖是我自己加进去的以外,另外四个都是必须添加的。因为weex_sdk底层是依赖他们的,只是以provided形式引入其中的,所以我们上层必须complie上。
文件位置如下:
blog7

2、初始化

在添加依赖以后,我们就开始正式写代码了,首先是需要将Weex在应用程序onCreate时候初始化:

public class WeexApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        InitConfig.Builder builder = new InitConfig.Builder();
        builder.setImgAdapter(new ImageAdapter());
//        builder.setHttpAdapter(new DefaultWXHttpAdapter());
        InitConfig config = builder.build();
        WXSDKEngine.initialize(this,config);
    }
}

weex的初始化主要是靠WXSDKEngine.initialize(this,config)函数,该函数声明如下:

public static void initialize(Application application, InitConfig config)

关键在于第二个参数InitConfig config,它是由InitConfig.Builder()构造得来的,InitConfig.Builder()中可以让我们通过setImgAdapter来设置自定义的图片加载器,通过setHttpAdapter来自定义网络请求方式。但我们有一点必须强调的是:weex的优势在于渲染,所以除了渲染以外的事情,都需要我们自己来做。也就是说加载图片和网络请求都需要我们自己来写方法实现;如果我们没有实现,那么当有图片加载请求和网络请求时,就不会执行任何实际代码,也就不会有任何效果!这也就是在初始化的时候,需要通过builder.setImgAdapter和builder.setHttpAdapter来设置自定义适配器的原因!庆幸的是,weex为我们实现了默认的网络请求适配器DefaultWXHttpAdapter,当发现我们在网络请求时,并没有定义网络适配器就会使用默认的DefaultWXHttpAdapter来请求网络。但可惜的是,weex并没有为我们实现默认的图片适配器,所以我们在初始化的时候必须实现自己的图片加载适配器,并通过 builder.setImgAdapter设置进去。如果我们没有写,那当需要加载图片的时候,就相当于执行了空方法,原来需要显示图片的地方就不会有任何显示!
然后我们来看看我们自定义的ImageAdapter是如何实现的:

public class ImageAdapter implements IWXImgLoaderAdapter {
  public ImageAdapter() {
  }
  @Override
  public void setImage(final String url, final ImageView view,WXImageQuality quality, WXImageStrategy strategy) {

    WXSDKManager.getInstance().postOnUiThread(new Runnable() {
      @Override
      public void run() {
        if (TextUtils.isEmpty(url)) {
          view.setImageBitmap(null);
          return;
        }
        String temp = url;
        if (url.startsWith("//")) {
          temp = "http:" + url;
        }
        if (view.getLayoutParams().width <= 0 || view.getLayoutParams().height <= 0) {
          return;
        }
        Picasso.with(WXEnvironment.getApplication())
            .load(temp)
            .into(view);
      }
    },0);
  }
}

在写适配器时,我们必须实现IWXImgLoaderAdapter接口,当需要加载图片时,就会通过IWXImgLoaderAdapter的setImage方法传过来,在setImage的参数中,第一个参数final String url表示网络图片地址,第二个参数,表示当前需要显示图片的View
我们这里只需要从网上加载图片,并将结果设置给View就可以了。哪种方法随意……我这里使用的Picasso,这也是为什么在依赖中添加Picasso依赖的原因

3、AndroidManifest配置

我们在自定义了Application以后,一样要记得在AndroidManifest.xml中引入:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.harvic.tryWeex.qijianweex.app">

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

    <application
            android:name=".WeexApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">
        <activity
                android:name=".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>

注意添加网络权限和引入WeexApplication

4、添加JS文件

首先将我们在文章开头的tech_list.js文件添加到工程中,在java文件夹的同级目录中,添加一个assets文件夹,将tech_list.js文件添加到其中
blog8

5、MyActivity加载JS文件

首先,需要说明一点,weex只负责渲染,渲染出来以后会返回一个结果View给我们,我们把它放到哪里就是我们自己来决定了,所以,首先,我们需要提供一个container来盛装返回的View,所以MyActivity的布局如下:(main.xml)

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

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

</RelativeLayout>

这里的FrameLayout,就是用来盛装结果用的Container;
然后MyActivity中的代码如下:

public class MainActivity extends AppCompatActivity {

    private FrameLayout mContainer;
    protected WXSDKInstance mWeexInstance;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mContainer = (FrameLayout)findViewById(R.id.container);
        mWeexInstance = new WXSDKInstance(this);
        mWeexInstance.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) {

            }
        });
        mWeexInstance.render("qijianWeex", WXFileUtils.loadFileContent("tech_list.js", this), null, null, -1, -1, WXRenderStrategy.APPEND_ASYNC);
    }
}

最关键是下面的三行代码:

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

   …………
});
mWeexInstance.render("qijianWeex", WXFileUtils.loadFileContent("tech_list.js", this), null, null, -1, -1, WXRenderStrategy.APPEND_ASYNC);

首先,我们使用mWeexInstance.render()函数就可以渲染本地的js文件了,在渲染成功以后,我们需要监听渲染结果,并将它添加到我们的container中,所以我们利用mWeexInstance.registerRenderListener()来监听渲染状态。当完成以后,会在onViewCreated中将渲染成功的View对象返回,我们只需要将它加载到container中显示出来即可。
如果我们需要加载远程js文件,可以使用:

mInstance.renderByUrl("pageName", "远程js地址", null, null, -1, -1, WXRenderStrategy.APPEND_ASYNC);

OK啦,到这里本篇就结束了,运行出来的效果就如开篇所示;
源码地址:http://gitlab.alibaba-inc.com/WeexDemo/qijianWeex

目录
相关文章
|
4月前
|
Java 关系型数据库 数据库
Android App连接真机步骤与APP的开发语言和工程结构讲解以及运行实例(超详细必看)
Android App连接真机步骤与APP的开发语言和工程结构讲解以及运行实例(超详细必看)
36 0
|
6月前
|
存储 传感器 定位技术
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
65 0
|
2月前
|
Java Android开发
[Android AIDL] --- AIDL工程搭建
[Android AIDL] --- AIDL工程搭建
16 0
|
6月前
|
测试技术 开发工具 数据库
《移动互联网技术》第十一章 Android应用工程案例: 掌握Android系统的需求分析和设计以及 Android项目的程序测试和版本管理方法
《移动互联网技术》第十一章 Android应用工程案例: 掌握Android系统的需求分析和设计以及 Android项目的程序测试和版本管理方法
71 0
|
8月前
|
XML Java Android开发
#4,Android Studio Android程序结构 工程目录介绍 文件作用 运行配置文件AndroidManifest.xml
#4,Android Studio Android程序结构 工程目录介绍 文件作用 运行配置文件AndroidManifest.xml
|
编解码 Android开发
Android | 老生常谈!屏幕适配原理 & 方案总结笔记
Android | 老生常谈!屏幕适配原理 & 方案总结笔记
477 0
Android | 老生常谈!屏幕适配原理 & 方案总结笔记
|
Android开发
android和Flutter的混合工程Demo
Flutter和Android混合工程的启动逻辑与纯Flutter应用程序的启动逻辑略有不同。在混合工程中,您需要在Android项目中添加一些额外的代码来启动Flutter引擎并加载Flutter代码。以下是整个app的启动逻辑的详细解释
android和Flutter的混合工程Demo
|
Android开发 iOS开发
android和flutter的混合工程启动逻辑
Flutter混合工程是指将Flutter代码集成到现有原生Android或iOS应用程序中的过程。在这种情况下,您需要在原生应用程序中添加一些代码来启动Flutter引擎并加载Flutter代码。以下是Flutter混合工程启动逻辑的详细说明
android和flutter的混合工程启动逻辑
|
开发工具 Android开发
Android推送集成方案总结
刚做完推送集成方案,记录下坑。 这里记录的特性和使用时针对写blog时采用的sdk的,具体使用流程和限制还请参考官方给出的sdk. #### 1、推送规则 小米手机用小米推送; 华为手机用华为推送; 其他手机用友盟推送。
|
存储 前端开发 数据管理
淘宝安卓端搜索架构升级总结
推荐语:这篇文章图文并茂地介绍了淘宝搜索滚动容器的技术演进过程,结合代码讲解页面结构划分、数据处理、交互效果,还包含了对逻辑抽象、功能拓展的思考,最后总结了可复用的架构。非常具有实践意义,推荐阅读学习! ——大淘宝技术终端开发工程师 门柳
288 0
淘宝安卓端搜索架构升级总结