简介
Weex 是一套简单易用的跨平台开发方案,能以 web 的开发体验构建高性能、可扩展的 native 应用,为了做到这些,Weex 与 Vue 合作,使用 Vue 作为上层框架,并遵循 W3C 标准实现了统一的 JSEngine 和 DOM API,这样一来,你甚至可以使用其他框架驱动 Weex,打造三端一致的 native 应用。
前期准准备
已经安装了JDK version>=1.7 并配置了环境变量
已经安装Android SDK 并配置环境变量。
Android SDK version 23 (compileSdkVersion in build.gradle)
SDK build tools version 23.0.1 (buildToolsVersion in build.gradle)
Android Support Repository >= 17 (for Android Support Library)
经过测试Android sdk的开发类库必须在23以上,可高不可低,低版本的类库会导致一些页面功能无法成功加载,所以
如果是老项目sdk过低要使用weex,不得不提供sdk了
Android 集成的两种方式
1.gradle 依赖集成
testCompile编译的类用不上也可以注销,还要注意引用的版本号和使用类库改成和原项目相同,经过测试目前的这个sdk
很好用的,仓库的app可以允许起来参考相关代码
2界面显示
显示的界面是一个Activity,需要注意的是必须继承AppCompatActivity,否则复杂界面会显示不全
public class NetworkActivity extends AppCompatActivity implements IWXRenderListener {
private static String weexurl = "http://192.168.1.55:8080/dist/hoteldetail.js";//请地址
private WXSDKInstance mWXSDKInstance;
private FrameLayout mContainer;
private HotelModule mHotelModule;
private NetworkActivity mContext;//上下文
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_network);
mContext = this;
CacheActivity.addActivity(NetworkActivity.this);
mContainer = (FrameLayout) findViewById(R.id.container);
hotelid = getIntent().getStringExtra("hotelid");
hotelname = getIntent().getStringExtra("hotelname");
HotelModule.setModuleListener(new HotelModule.ModuleListener() {
@Override
public void pickImage(int size) {
});//交互回调
/**
* pageName:自定义,一个标示符号。
* url:远程bundle JS的下载地址
* options:初始化时传入WEEX的参数,比如 bundle JS地址
* flag:渲染策略。WXRenderStrategy.APPEND_ASYNC:异步策略先返回外层View,其他View渲染完成后调用onRenderSuccess。WXRenderStrategy.APPEND_ONCE 所有控件渲染完后后一次性返回。
*/
mWXSDKInstance = new WXSDKInstance(this);
mWXSDKInstance.registerRenderListener(this);
Map options = new HashMap<>();
options.put(WXSDKInstance.BUNDLE_URL, weexurl);//请求网址可以通过options传给后台相要的参数 根据需求自行添加,请求成功后就可以看到网页了
options.put("hotelId", hotelid);
options.put("hotelName", hotelname);
mWXSDKInstance.renderByUrl("WXSample", weexurl, options, null, WXRenderStrategy.APPEND_ONCE);
}
@Override
protected void onStart() {
super.onStart();
if (mWXSDKInstance != null) {
mWXSDKInstance.onActivityStart();
}
}
@Override
protected void onResume() {
super.onResume();
if (mWXSDKInstance != null) {
mWXSDKInstance.onActivityResume();
}
Log.e("hotel6", "weex活动resume");
}
@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();
}
}
@Override
public void onViewCreated(WXSDKInstance instance, View view) {
if (view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
mContainer.addView(view);//加载成功拿的是一个view,最后填充到视图中
}
@Override
public void onRenderSuccess(WXSDKInstance instance, int width, int height) {
}
@Override
public void onRefreshSuccess(WXSDKInstance instance, int width, int height) {
}
@Override
public void onException(WXSDKInstance instance, String errCode, String msg) {
}
}
weex调用本地,细心的读者发现在全局盒子注册的时候有一行
WXSDKEngine.registerModule("hotelModule", HotelModule.class);
这个就是交互的核心类,类名可以自己定,前面的字符串key必须和weex一样,这样才能匹配,下面看看这个类
public class HotelModule extends WXModule {//首先需要继承WXModule
private static ModuleListener mModuleListener;//这个接口回调用于本类调用显示界面的activity
public ModuleListener getModuleListener() {
return mModuleListener;
}
public static void setModuleListener(ModuleListener moduleListener) {
mModuleListener = moduleListener;
}
private View view;
public View getView() {
return view;
}
public void setView(View view) {
this.view = view;
}
@JSMethod //加上这行注解,方法名跟weex统一一样,weex就可以调用了
public void goBack() {
CacheActivity.finishActivity();//因为本类拿不到finish的上下文,如何结束界面可以通过写一个活动管理栈来结束,
活动加入通过生命周期,不是本文重点
}
@JSMethod
public void getScreenWidth(JSCallback callback) {
Map data = new HashMap<>();
data.put("width", PageChangedManager.widthPixels);
callback.invoke(data);//本地通过hashmap传值给weex,key 方法名需要统一
}
// 获取token
@JSMethod
public void GetAccessTokenApp(JSCallback callback) {
Map data = new HashMap<>();
data.put("access_token", Util.getNetHeader());
callback.invoke(data);
}
@JSMethod
public void getAppSystem(JSCallback callback) {
Map data = new HashMap<>();
data.put("system", "android");
callback.invoke(data);
}
public interface ModuleListener {//weex调用本地方法,我们又想调用原来显示的活动可以通过接口回调
void pickImage(int size);
}
}
本地调用weex的方法 String[] strings = new String[data.size()];
data.toArray(strings);
//方法名要统一,传入值使用数组
Map params=new HashMap<>();
params.put("images",strings);
mWXSDKInstance.fireGlobalEventCallback("uploadImages",params);
活动管理类
public class CacheActivity {
public static List activityList = new LinkedList();
public CacheActivity() {
}
/**
* 添加到Activity容器中
*/
public static void addActivity(Activity activity) {
if (!activityList.contains(activity)) {
activityList.add(activity);
}
}
/**
* 便利所有Activigty并finish
*/
public static void finishActivity() {
for (Activity activity : activityList) {
activity.finish();
}
}
/**
* 结束指定的Activity
*/
public static void finishSingleActivity(Activity activity) {
if (activity != null) {
if (activityList.contains(activity)) {
activityList.remove(activity);
}
activity.finish();
activity = null;
}
}
/**
* 结束指定类名的Activity 在遍历一个列表的时候不能执行删除操作,所有我们先记住要删除的对象,遍历之后才去删除。
*/
public static void finishSingleActivityByClass(Class> cls) {
Activity tempActivity = null;
for (Activity activity : activityList) {
if (activity.getClass().equals(cls)) {
tempActivity = activity;
}
}
finishSingleActivity(tempActivity);
}
}
weex官网地址http://weex.apache.org/cn/guide/integrate-to-your-app.html
阿里成熟的项目地址 https://github.com/apache/incubator-weex/tree/master/android 官方文档还给了一个简单demon,可以
看一下集成逻辑,实际上存在问题无法满足需求
开发使用目前还要使用上面推荐的这个项目sdk
需要注意ndk 配置官方支持这两种,项目发现其他的架构出现了在部分手机上不显示图片问题,目前把其他的注销了,只使用了
这两种,weex还有待完善。
ndk {
// 设置支持的 SO 库构架,一般而言,取你所有的库支持的构架的`交集`。
abiFilters 'armeabi','x86'//
}