最近为了项目需要(实际上是为了年底KPI),领导要求用3天时间,学习并使用weex开发一个页面,说实话,压力山大。在这之前压根儿就没听说过啊,一脸懵逼

无奈之余只能Google了,惊喜的发现weex的官网上面是什么都有啊,环境搭建、weex集成开发、js教程等等还有好多,双手奉上官网地址:http://weex.apache.org/cn/

既然官网讲的这么全面,我就只说一下我的操作流程;

1、weex环境搭建

首先下载安装node.js,node.js是weex编译、打包用的基础工具,javascript和node.js关系,类似于java与jvm,nodejs去官方网站下载最新稳定版6.xx就可以

安装好了之后,用以下命令检查是否安装成功

node -v
npm -v

出现上图就说明node.js安装成功了

npm是nodejs的包管理工具,相当于android中的gradle或者iOS中的cocoapods,但是npm在国内访问速度较慢,建议大家安装cnpm,是淘宝的一个npm国内镜像

安装完cnpm后执行cnpm install -g weex-toolkit安装weex-toolkit

$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ cnpm install -g weex-toolkit

命令行敲weex,出现上图就说明weex-toolkit安装成功了。

至此weex的安装就告一段落了,官网上的环境搭建到这里之后还有几步,不过我都没有用上,这里先记一下,后续需要用到了再补充!!!!!!

2、集成到 Android

接下来就是将weex项目集成到Android项目中去,这块真是没有什么好讲的,这块就和集成第三方sdk一毛一样的

直接上官网的集成方式:http://weex.apache.org/cn/guide/integrate-to-your-app.html

2-1、个人对weex开发的理解

说一下我对在Android中集成weex的理解吧,可能理解的很浅显,不喜勿喷!

weex旨在“一次撰写,多端使用”,意思是,用weex写的页面,不论是Android还是iOS甚至web端都可以使用,这样的话就可以极大的降低开发成本,

weex其实就是写的一个类似于h5的页面(js编写),写完之后将vue文件编译、部署到Nginx服务器上(Nginx服务器后面会讲到),这时候在你的Nginx服务器下的html文件夹内会生成一个.js的文件,这个.js文件就是你要嵌入到Android项目内的文件,如果一个项目内有很多个weex页面,就需要编译部署很多个vue文件,也就是说会在html这个文件夹下生成很多个.js文件,然后你可能会问,那我们要怎么管理和维护这么多个.js文件呢?这就需要我们将这些个.js压缩成一个zip包,把这个压缩后的zip包个后台,后台会生成一个json文件,将这个.json放在Nginx服务器的html文件夹内,我们需要做的就只是管理和维护这个.json文件就可以了,最后在你的Android项目内,访问这个Nginx服务器(服务器的地址就是你电脑的ip地址),获取到服务器上的weex页面(其实这也能做到预加载的作用)然后进行各种处理和操作;

生成的.json文件就是这么个东西,在后文要讲的获取页面,完全靠这里面的url,非常的重要;

贴一些util代码吧:

    //在mainActivity或者启动页获取weex相关json文件
WeexUtils.getPages(); public static void getPages() { new Thread(new Runnable() {
@Override
public void run() {
String url = http://ip地址/后台生成的.json文件;
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.build();
try {
okhttp3.Response response = AlbatrossApplication.getInstance().getClient().newCall(request).execute();
String data = response.body().string();
      //okhttp请求.json数据,最后将请求到的数据通过sharedprefer存储到本地
SharedPreferences pages = AlbatrossApplication.getInstance().getSharedPreferences("pages", MODE_PRIVATE);
pages.edit().putString("pages", data).commit(); downloadBundle();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}

下载weex bundle:

    /**
* 下载weex bundle
*/
public static void downloadBundle() {
new Thread(new Runnable() {
@Override
public void run() {
try {
SharedPreferences pages = AlbatrossApplication.getInstance().getSharedPreferences("pages", MODE_PRIVATE);
String pagesData = pages.getString("pages", "");
com.alibaba.fastjson.JSONObject jsonObject = JSON.parseObject(pagesData);
String url = jsonObject.getJSONObject("zip").getString("url");
String path = AlbatrossApplication.getInstance().getCacheDir() + File.separator + "weex";
if (!new File(path).exists()) {
new File(path).mkdirs();
}
File downloadedFile = new File(path, "js_bundle.zip");
String localMd5 = WeexUtils.calculateMD5(downloadedFile);
if (jsonObject.getJSONObject("zip").getString("md5").equals(localMd5)) {
//本地zip和服务器zip一致,return
return;
} okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.build(); okhttp3.Response response = AlbatrossApplication.getInstance().getClient().newCall(request).execute();
BufferedSink sink = Okio.buffer(Okio.sink(downloadedFile));
sink.writeAll(response.body().source());
sink.close();
Log.e("bobo", downloadedFile.length() + " " + downloadedFile.getAbsolutePath());
WeexUtils.unzip(downloadedFile, new File(path));
Log.e("bobo 当前目录文件数", new File(path).listFiles().length + ""); // downloadPatch();//下载patch
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}

以上的操作就可以获取到weex页面了,获取到了之后就可以开始操作了,这里我就简单的举一个点击跳转的例子好了,上代码

        View view = findviewById(R.id.tv_consist);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
WXSDKInstance mWXSDKInstance = new WXSDKInstance(getActivity());
Intent intent = new Intent(getActivity(), WeexActivity.class);
intent.putExtra("WX_URL", "/html文件夹下的js文件.js");
mWXSDKInstance.getContext().startActivity(intent);
}
});

跳转到WeexActivity后,在WeexActivity进行的处理就是将前文存储在本地的数据解析,根据解析后的数据获取到指定.js文件的路径,最后加载这个路径的页面,这块挺乱的,我说的只是一个大概方向,具体的还要看实际情况;

public class WeexActivity extends BaseMainActivity implements View.OnClickListener, IWXRenderListener {
private String TEST_URL = "http://172.16.36.232/dist/jump.js";
private WXSDKInstance mWXSDKInstance;
private FrameLayout mContainer;
private TextView mTv_title;
private HashMap<String, String> mLocalBundleBean;
private TextView mTv_right;
private boolean isFinish = true;
private View mTv_left; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// KYApplication.getInstance().addActivity(this);
setContentView(R.layout.activity_weex);
initView(); WXSDKEngine.setActivityNavBarSetter(new NavigatorAdapter());
mContainer = (FrameLayout) findViewById(R.id.container);
mWXSDKInstance = new WXSDKInstance(this);
mWXSDKInstance.registerRenderListener(this);
/**
* pageName:自定义,一个标示符号。
* url:远程bundle JS的下载地址
* options:初始化时传入WEEX的参数,比如 bundle JS地址
* flag:渲染策略。WXRenderStrategy.APPEND_ASYNC:异步策略先返回外层View,其他View渲染完成后调用onRenderSuccess。WXRenderStrategy.APPEND_ONCE 所有控件渲染完后后一次性返回。
*/
Map<String, Object> options = new HashMap<>();
String wx_url = getIntent().getStringExtra("WX_URL");
String title = getIntent().getStringExtra("title");
// mTv_title.setText(title);
TEST_URL = wx_url.substring(wx_url.lastIndexOf("/")+);
options.put(WXSDKInstance.BUNDLE_URL, TEST_URL); //获取集合,维护文件md5值以及文件对应路径
//从json文件里,取出md5对应的文件,有则加载文件,无则加载url
SharedPreferences pages = getSharedPreferences("pages", MODE_PRIVATE);
String pageData = pages.getString("pages", ""); JSONObject jsonObject = JSON.parseObject(pageData);
JSONArray jsonArray = jsonObject.getJSONArray("pages"); HashMap<String, PageBean> pageMap = new HashMap<>();//存储服务器最新页面信息
for (int i = ; i < jsonArray.size(); i++) {
PageBean pageBean = JSON.parseObject(jsonArray.getString(i), PageBean.class);
pageMap.put(pageBean.getPage(), pageBean);
} mLocalBundleBean = new HashMap<>();
try {
long time = System.currentTimeMillis();
getAllFiles(new File(Constant.WEEX_URL));//本地zip包解压文件md5
Log.e("bobo", "计算md5总耗时" + (System.currentTimeMillis() - time));
} catch (Exception e) {
e.printStackTrace();
} PageBean pageBean = pageMap.get(TEST_URL);//获取login.js对应的md5、url
if(pageBean==null){
Toast.makeText(this,"页面不存在", Toast.LENGTH_SHORT).show();
return;
}
String localUrl = mLocalBundleBean.get(pageBean.getMd5());
TEST_URL=pageBean.getUrl();
if (null != localUrl) {
mWXSDKInstance.render(TEST_URL, WXFileUtils.loadFileOrAsset(localUrl, this), null, null, WXRenderStrategy.APPEND_ASYNC);
Log.e("bobo","从本地加载");
} else {
mWXSDKInstance.renderByUrl(TEST_URL, TEST_URL, options, null, WXRenderStrategy.APPEND_ONCE);
Log.e("bobo","从网络加载");
}
// mWXSDKInstance.renderByUrl("WXSample", TEST_URL, options, null, WXRenderStrategy.APPEND_ONCE);
} public void initView() {
mTv_left = findViewById(R.id.tv_left);
mTv_title = (TextView) findViewById(R.id.tv_title);
mTv_right = (TextView) findViewById(R.id.tv_right);
mTv_left.setOnClickListener(this);
mTv_title.setOnClickListener(this);
mTv_right.setOnClickListener(this);
} @Override
public void onClick(View view) {
if (view.getId() == R.id.tv_left) {
if(isFinish){
super.onBackPressed();
}else {
mWXSDKInstance.fireGlobalEventCallback("left_click", null);
}
} else if (view.getId() == R.id.tv_title) {
// Toast.makeText(this, "标题点击了", Toast.LENGTH_SHORT).show();
} else if (view.getId() == R.id.tv_right) {
mWXSDKInstance.fireGlobalEventCallback("clickrightitem", null);
}
} @Override
protected void onStart() {
super.onStart();
if (mWXSDKInstance != null) {
mWXSDKInstance.onActivityStart();
}
} @Override
protected void onResume() {
super.onResume(); WXStorageModule wxStorageModule = new WXStorageModule();
wxStorageModule.setItem("currentPage", WXUtils.getNameFromUrl(TEST_URL),null); if (mWXSDKInstance != null) {
mWXSDKInstance.onActivityResume(); //发送页面出现广播
Map<String, Object> params = new HashMap<>();
params.put("page", WXUtils.getNameFromUrl(TEST_URL));
mWXSDKInstance.fireGlobalEventCallback("appear", params);
}
} @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();
// KYApplication.getInstance().deleteActivity(this);
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); //发送页面出现广播
Map<String, Object> params = new HashMap<>();
params.put("page", WXUtils.getNameFromUrl(TEST_URL));
mWXSDKInstance.fireGlobalEventCallback("appear", params);
} @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) { } private class NavigatorAdapter implements IActivityNavBarSetter { @Override
public boolean push(String param) {
return false;
} @Override
public boolean pop(String param) {
return false;
} @Override
public boolean setNavBarRightItem(String param) {
String title = JSON.parseObject(param).getString("title"); if(!TextUtils.isEmpty(title) && ("添加报价".equals(title) || "返回首页".equals(title))){
mTv_right.setTextColor(getResources().getColor(R.color.color_5E8BF8));
}
mTv_right.setText(title);
return false;
} @Override
public boolean clearNavBarRightItem(String param) {
return false;
} @Override
public boolean setNavBarLeftItem(String param) {
return false;
} @Override
public boolean clearNavBarLeftItem(String param) {
return false;
} @Override
public boolean setNavBarMoreItem(String param) {
return false;
} @Override
public boolean clearNavBarMoreItem(String param) {
return false;
} @Override
public boolean setNavBarTitle(String param) {
String title = JSON.parseObject(param).getString("title");
mTv_title.setText(title);
return false;
}
} public void getAllFiles(File file) throws Exception {
File[] files = file.listFiles();
// long time = System.currentTimeMillis();
for (int i = ; i < files.length; i++) {
if (files[i].isDirectory()) {
getAllFiles(files[i]);
} else {
Log.e("bobo", "name" + files[i].getName() + " md5" + WeexUtils.calculateMD5(files[i]));
mLocalBundleBean.put(WeexUtils.calculateMD5(files[i]), files[i].getAbsolutePath());
}
}
} /**
* @return get mWXSDKInstance
*/
public WXSDKInstance getWXSDKInstance() {
return mWXSDKInstance;
} @Override
public void onBackPressed() {
if(isFinish){
super.onBackPressed();
}else {
mWXSDKInstance.fireGlobalEventCallback("back_click", null);
}
} /**
* Sets the isFinish 设置是否直接返回上个页面
* You can use getFinish() to get the value of isFinish
*/
public void setFinish(boolean finish) {
isFinish = finish;
} public void hideBackButton(){
mTv_left.setVisibility(View.GONE);
}
}

3、Nginx服务器

终于到最后一步了,Nginx服务器下载地址:http://nginx.org/en/download.html

我是下载的稳定版

下载完之后解压到文件夹下,双击nginx.exe启动服务,打开conf这个文件夹,打开nginx.conf这个文件,修改location下的root

3-1、编译、部署.vue文件

哦。对了,大家应该都是到用webstorm写vue页面吧??哈哈哈哈

(1)首次创建项目或者是首次导入项目的时候,需要在控制台执行:cnpm install,这个就类似于Android studio中的sync now。

我们需要通过这个命令将package.json中的所有依赖下载下来;

(2)同样的,控制台执行:weex compile src/vue文件名 D:\nginx\nginx-1.12.2\html

意思是将制定的vue文件编译到nginx服务器下的指定文件夹内,这时候就会生成一个前文所说到的.js文件。

终于全都结束了,这是我今天一天的调研学习的成果,可能有一些地方理解的有偏差或者不对的地方,非常欢迎大家批评指正

如果有任何疑问,欢迎留言~~~~

                                                    2017/12/6 21:05 晚安各位

Android weex的集成和开发的更多相关文章

  1. WEEX SDK集成到工程(Integrate to Android) #25

    WEEX SDK集成到工程(Integrate to Android) #25 https://github.com/weexteam/article/issues/25

  2. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  3. [Android] 环境配置之基础开发环境(SDK/Android Studio)(转)

    [Android] 环境配置之基础开发环境(SDK/Android Studio)   博客: blog.csdn.net/qiujuer 网站: www.qiujuer.net 开源库: Geniu ...

  4. Android 系统移植与驱动开发--第二章搭建Android环境核心步骤及心得

    第二章 搭建Android 开发环境 虽然在这一章中讲的是Android底层开发环境,但是相应伴随的还有Android NDK程序来测试Linux驱动,HAL程序库.底层开发不仅需要交叉编译环境,还要 ...

  5. Jenkins构建Android项目持续集成之findbugs的使用

    Findbugs简介 关于findbugs的介绍,可以自行百度下,这里贴下百度百科的介绍.findbugs是一个静态分析工具,它检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题 ...

  6. Xamarin.Android VSTS 持续集成

    这些天做了一个基于 VSTS 的 Xamarin.Android的持续集成,这里分享下 Build Agent 环境需求 DotNetFramework msbuild visualstudio An ...

  7. 第一章 Android系统移植与驱动开发概述

    本书第一章首先简单概要地介绍了关于Android系统移植和驱动开发的相关内容. 所谓“移植”是指为特定的自己的设备,如手机定制Android的过程.自己开发一些程序(移植)装载在设备上,使得Andro ...

  8. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  9. Android Studio1.4.x JNI开发基础-基本环境配置

    从Eclipse时代到Android Studio普及,开发工具越来越好用.早些时候还需要安装Cygwin工具,从Android Studio1.3以后,在Android 环境开发JNI程序搭建开发环 ...

随机推荐

  1. 设置第三方的SMTP服务

    取得授权码:

  2. js中自执行函数写法

    //自执行写法1 (function T(){ alert(1) })() //自执行写法2 var T1=function(){ alert(1) }(); //传值 var para1={a:1; ...

  3. jQuery懒加载插件 – jquery.lazyload.js

    Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...

  4. 添加ASP.NET网站资源文件夹

    ASP.NET应用程序包含7个默认文件夹,分别为Bin.APP_Code.App_GlobalResources.App_LocalResources.App_WebReferences.App_Br ...

  5. web测试工具总结

     纯粹的手工测试早已不满足如今的项目需求,各种测试工具的应用早已成为普遍趋势.如何选取合适的工具来完成对应的测试工作?本文将针对Web测试,列举 一些推荐的测试工具,并加以简单介绍. (每个工具的实际 ...

  6. C#中加粗label的字体

    1. 在C#的代码中想直接加粗label控件的字体, label1.Font.Bold = true;//发现系统会提示Font.Bold是只读属性 如果必须要加粗字体呢,方法如下: 2. 使用Fon ...

  7. replaceAll的一个bug

    String replaceAll(regex, replacement)函数 , 由于第一个参数支持正则表达式,replacement中出现“$”,会按照$1$2的分组模式进行匹配,当编译器发现“$ ...

  8. [转]象棋AI算法(一)

    本文转自:http://blog.csdn.net/u012723995/article/details/47133693 参考文献:http://www.xqbase.com/computer/se ...

  9. SEO 小技巧汇总

    一.为了提高搜索点击率,还可以   1.为了增加关键词的密度,将关键字隐藏在页面里(将文字颜色定义成与背景颜色一样). 2.在图象的alt注释语句中加入关键字. 如:<IMG SRC=" ...

  10. DIY了一下自己blog的UI

    当年才学前端时就想改自己blog的UI,然鹅当时没看见那个“申请JS权限”,一直以为blog不能随意DIY样式,只改了少许CSS.现在重新看看设置管理选项,简单修改了一下样式(注意:修改样式之前发邮件 ...