开始琢磨在Android端使用Weex已经一周多了,Weex的官方文档看了不少,前端的知识也看了一些,也算是入了个门。但是在实践的过程中发现有一些官方文档说的不清楚的地方,必须要看官方例子才能搞明白,于是把这个实践过程做一些记录,也好方便更多的人实践。
自己实践过程中可能会有一些错误,如有错误请及时指正。
一、Android端引入
使用gradle引入的方式官方文档中的方式如下
- 创建Android工程,没有什么要特别说明的,按照你的习惯来。
- 修改build.gradle 加入如下基础依赖
compile 'com.android.support:recyclerview-v7:23.1.1'
compile 'com.android.support:support-v4:23.1.1'
compile 'com.android.support:appcompat-v7:23.1.1'
compile 'com.alibaba:fastjson:1.1.46.android'
compile 'com.taobao.android:weex_sdk:0.5.1@aar'
注意两点:
(1)support库最好根据你项目的版本来设定
(2)Weex最新版为0.18.0,官方文档已经滞后了,所以最好为:
compile 'com.taobao.android:weex_sdk:0.18.0'
另外,不建议使用源码依赖的方式,错误太多,基本上新手很难解决。
二、Android端渲染Api的调用
理解Weex的基本原理之后,相信很多人就能明白,在一个纯Weex-Android工程中,Android端主要任务就是渲染Weex页面显示出来(Weex -> Native),那么Activity的渲染操作分为两种类型:
(1)本地渲染:渲染本地的js文件
(2)远程渲染:渲染网络的js文件
这两种官方文档主要只介绍了第一种,并且实例中关键代码如下:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWXSDKInstance = new WXSDKInstance(this);
mWXSDKInstance.registerRenderListener(this);
/**
* WXSample 可以替换成自定义的字符串,针对埋点有效。
* template 是.we transform 后的 js文件。
* option 可以为空,或者通过option传入 js需要的参数。例如bundle js的地址等。
* jsonInitData 可以为空。
* width 为-1 默认全屏,可以自己定制。
* height =-1 默认全屏,可以自己定制。
*/
mWXSDKInstance.render("WXSample", WXFileUtils.loadFileContent("hello.js", this), null, null, -1, -1, WXRenderStrategy.APPEND_ASYNC);
}
但是实际上通过Playground官方示例发现这已经不是推荐写法了,Playground地址如下:
apache/incubator-weexgithub.com
其中关键代码我们用第二种加载url为示例:
private void loadWXfromService(final String url) {
if (mWXSDKInstance != null) {
mWXSDKInstance.destroy();
}
RenderContainer renderContainer = new RenderContainer(this);
mContainer.addView(renderContainer);
mWXSDKInstance = new WXSDKInstance(this);
mWXSDKInstance.setRenderContainer(renderContainer);
mWXSDKInstance.registerRenderListener(this);
mWXSDKInstance.setBundleUrl(url);
mWXSDKInstance.setTrackComponent(true);
WXHttpTask httpTask = new WXHttpTask();
httpTask.url = url;
httpTask.requestListener = new WXRequestListener() {
@Override
public void onSuccess(WXHttpTask task) {
Log.i(TAG, "into--[http:onSuccess] url:" + url);
try {
mConfigMap.put("bundleUrl", url);
mWXSDKInstance.render(TAG, new String(task.response.data, "utf-8"), mConfigMap, null, ScreenUtil.getDisplayWidth(MainFirstActivity.this), ScreenUtil.getDisplayHeight(MainFirstActivity.this), WXRenderStrategy.APPEND_ASYNC);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
@Override
public void onError(WXHttpTask task) {
Log.i(TAG, "into--[http:onError]");
Toast.makeText(getApplicationContext(), "network error!", Toast.LENGTH_SHORT).show();
}
};
WXHttpManager.getInstance().sendRequest(httpTask);
}
通过这个实例,我们可以看出来老的api:renderByUrl已经被废弃。老Api的问题我看到网上有不少,我自己也遇到了,比如list和tab-bar一起使用list不显示、crash等。
而这种推荐写法其实就是基于一个Http工具,自己完成Http请求并且将原始数据通过render直接渲染,虽然我也不清楚和原始Api的区别,但是完全解决了我遇到的问题。
三、ImageAdapter实现注意
按照官方文档,我们要自行实现一个ImageAdapter,这个大家都清楚,具体实现Api如下:
public class ImageAdapter implements IWXImgLoaderAdapter {
@Override
public void setImage(String url, ImageView view, WXImageQuality quality, WXImageStrategy strategy) {
//实现你自己的图片下载,否则图片无法显示。
}
}
但是如果使用Glide一类库实现时,如果不注意Activity生命周期问题,会报错:
You cannot start a load for a destroyed activity
其实就是在Activity已经被销毁之后,Glide会进行Activity加载,简单的解决办法就是判断一下即可:
if (view.getContext() instanceof Activity) {
if (((Activity) view.getContext()).isDestroyed()) {
return;
}
}
但更好的做法还是可以参考官方实现,考虑的问题更全面。
后面还会继续进行这方面学习,在做的过程中再抽象出一些东西,比如跳转的一些实现方式和尝试,都会在Demo中慢慢去实现。
网友评论