记录weex接入过程
2017-01-03 16:39
387 查看
http://ie8384.com/blog/?p=1452
目前weex已在尚妆旗下的达人店app上线了一个常用的订单管理页面,截止目前Android上未发现问题,渲染时间在100-300ms之间。
作为Android开发,此文首先会从Android的角度为主来记录接入的过程,希望给未接入的同学更方便省时地接入weex提供一点帮助。其中会涉及到预加载,降级,热更新,以及在app不更新的情况下动态配置新页面等问题,这些Android和iOS都是统一的逻辑,希望和大家一起交流。前端方面可以参考我同事写的《weex入门实践(前端视角)》。
其实对于module、component的定义,以及IWXImgLoaderAdapter、IWXHttpAdapter等adapter的重写,在playgroud和weexteam里都已经有很好的例子了。
在原来的project上,新建单独的
weex module。代码结构如下:
通过类WeexManager来统一管理weex相关的配置,以下是init的主要内容,在application的onCreate里调用:
1)考虑到第一次接入weex,有点担心兼容问题,万一引起崩溃等不确定因素,所以这里做了一个开关。其实每接入一个新的sdk都最好有个开关,以避免因为不确定因素导致不稳定。
2)weexDir是js的下载存储路径,为了加快页面打开时间,会对js进行预加载到本地
3) sdk对a标签的处理只调用了"event"的openURL接口,但是却没有注册"event"。所以需要自己实现WXEventModule,并注册。
4)ModalModule的实现参考sdk里的WXModalUIModule
5)FrescoImageAdapter和FrescoImageComponent的实现参考weexteam里的FrescoImageAdapter实现和FrescoImageComponent实现,支持webp,支持压缩,支持没有协议的链接(忽略协议可以让浏览器根据页面时http或者https自动选择使用的协议,从而避免了网站改为https的情况下仍然访问http资源而无法访问的问题。)
6)OkHttpAdapter的实现参考github上zjutkz同学的实现 OkHttpAdapter,感谢,经过改写,支持没有协议的链接
7)ShopModule是自定义的Module,定义通用的一些接口,比如设置title bar是否显示,以及title bar的title;关闭当前页面,分享,错误日志收集等。
这边考虑到以后页面有可能嵌入到其他activity,或者把weex的渲染放入新建的WeexFragment。然后新建WeexActivity来引用该WeexFragment 。所有的单独页面的weex渲染都使用这个activity,非单独页面的使用weexFragment,这样新加页面时,无需重新注册activity。weex处理逻辑统一,方便管理,方便动态配置。通过统一跳转协议跳转到WeexActivity,通过intent传入两个参数url和h5。
url:js链接,可以是本地的存储地址/sdcard/com.showjoy.shop/weex/order.js,也可以是线上链接 https://xxxxx/0.4.3/order.js
h5:用来降级的h5页面链接,当渲染失败时,会跳转到该h5页面
首先实例化WXSDKInstance
1)当前类实现接口IWXRenderListener,可以参考weexteam里的AbsWeexActivity实现
2)注册的广播是DefaultBroadcastReceiver,可以可以参考weexteam里的AbsWeexActivity实现
然后讲一下渲染,支持本地js以及线上js
其中,getPageName()自定义即可,getDisplayWidth和getDisplayHeight获取屏幕宽高。
传入本地的存储地址时,先读取文件,然后同个Handler在UI线程渲染,如下:
这里getLifeState()是我们自己BaseActivity的实现,可以自行判断。SHJump和finishActivity都是自己的实现,大家自己实现即可。
渲染回调的实现,按需要处理即可,渲染成功后隐藏loading,view创建后添加view。渲染异常时降级跳转到h5。例如:
为了实现如图的tab,一开始在.we文件里使用tabbar组件,后来发现在Android机型适配上不够好。于是后来就将两个tab做成两个页面,生成两个js文件。首先渲染“我的订单.js”,生成如下的界面。然后点击“本店订单”时,调用自定义module里的接口loadPage,参数为h5的链接。三端实现接口loadPage,h5直接跳转,而iOS和Android通过h5链接从weex跳转配置里找到对应的js,重新渲染显示。下面具体做几点说明:
1)定义Map<String, WXSDKInstance> wxsdkInstanceMap;来存储不同js的WXSDKInstance,定义Map<String,
View> viewMap来存储不同js渲染后的View。之所以要存储多个WXSDKInstance,是因为WXSDKInstance不能重复渲染,而且当WXSDKInstance
destory后,之前渲染的view里的内容也会被清空。注意在在页面destory时,记得把所有WXSDKInstance都destory就好了。
2)viewMap里的key对应页面的js。点击tab切换页面时,如对应的js已渲染,则直接取出view来显示。
3)上文提到的weex跳转配置,在以下的跳转规则里一同介绍。
跳转规则如下图,如果看不清,可以到新页面放大查看,主要介绍一下两个配置参数:
1)参数interceptUrlList可以动态配置需要拦截的h5链接,然后生成统一跳转地址
showjoyshop://page.sh/order
示例如下:
page:对应统一跳转协议,即与weex配置里的page一致;
url:需要匹配的链接的正则表达式
v:最低版本支持
2)然后通过order在参数weexPages里查找对应的js信息,然后渲染。
示例如下:
page:
对应统一跳转的 path
url:
需要渲染的js,
md5:
js文件的md5值用于校验,
h5:
渲染失败后的降级方案,
v:
最低支持的版本号
这样就达到了动态拦截,动态上线weex的目的。
前面讲到为了加快weex打开时间,会预加载js,这里就介绍一下js预加载的实现。
1)每次更新完配置文件,遍历,查看是否存在md5一致的page_xxx.js文件,如果不存在则更新.
2)下载完成后,保存格式为xxx.js,校验md5
相同的话,记录文件的最后修改时间;
不同的话,删除已下载文件,重新下载,重复校验流程。
3)支持统一跳转协议,page对应目前app端的统一跳转协议里的page,有必要的时候可以替换原来的native页面,解决native页面错误不能及时修复的问题。加载失败的话,打开h5页面。
4)每次打开指定页面的时候,先检查本地是否有对应page文件,再检验最后修改时间是否跟记录的一致
一致就加载
不一致就用线上url。
问题一:上线后,发现在一些机型渲染失败,public
void onException(WXSDKInstance instance, String errCode, String msg)回调里,errCode返回wx_create_instance_error,msg返回createInstance
fail!
解决办法:将apk解压出来后,发现编译出了支持5种abi的包。然而libweexv8.so只在armeabi和x86里有,缺少对其它三种abi的支持,那么如果应用运行于arm64-v8a,x86_64,armeabi-v7a为首选abi的设备上时,就会加载失败了。其实arm64-v8a,armeabi-v7a,x86_64这三个abi,应用并不是必须要做支持,手机一般都会提供自动兼容。所以我们只要把对x86,
arm64-v8a,x86_64的支持去掉就可以。如下在主模块的build.gradle的android里的defaultConfig内添加如下内容:
问题二:OkHttpAdapter里调用onHttpFinish出现解析异常,日志如下:
解决方法:catch异常
问题三:线上线下环境切换问题。
解决方法:在.we文件里链接以及请求地址使用相对地址,h5页面自动选择该页面使用的域名,而在iOS和Android都做拦截处理,根据当前环境添加相应的域名。
参考链接:
https://github.com/weexteam/
http://weex-project.io/doc/
https://github.com/alibaba/weex/
目前weex已在尚妆旗下的达人店app上线了一个常用的订单管理页面,截止目前Android上未发现问题,渲染时间在100-300ms之间。
作为Android开发,此文首先会从Android的角度为主来记录接入的过程,希望给未接入的同学更方便省时地接入weex提供一点帮助。其中会涉及到预加载,降级,热更新,以及在app不更新的情况下动态配置新页面等问题,这些Android和iOS都是统一的逻辑,希望和大家一起交流。前端方面可以参考我同事写的《weex入门实践(前端视角)》。
一、Android接入过程
其实对于module、component的定义,以及IWXImgLoaderAdapter、IWXHttpAdapter等adapter的重写,在playgroud和weexteam里都已经有很好的例子了。
1、gradle依赖
2、新建weex
module
在原来的project上,新建单独的weex module。代码结构如下:
3、初始化weex
通过类WeexManager来统一管理weex相关的配置,以下是init的主要内容,在application的onCreate里调用:2)weexDir是js的下载存储路径,为了加快页面打开时间,会对js进行预加载到本地
3) sdk对a标签的处理只调用了"event"的openURL接口,但是却没有注册"event"。所以需要自己实现WXEventModule,并注册。
4)ModalModule的实现参考sdk里的WXModalUIModule
5)FrescoImageAdapter和FrescoImageComponent的实现参考weexteam里的FrescoImageAdapter实现和FrescoImageComponent实现,支持webp,支持压缩,支持没有协议的链接(忽略协议可以让浏览器根据页面时http或者https自动选择使用的协议,从而避免了网站改为https的情况下仍然访问http资源而无法访问的问题。)
6)OkHttpAdapter的实现参考github上zjutkz同学的实现 OkHttpAdapter,感谢,经过改写,支持没有协议的链接
7)ShopModule是自定义的Module,定义通用的一些接口,比如设置title bar是否显示,以及title bar的title;关闭当前页面,分享,错误日志收集等。
4、新建统一的weex页面
这边考虑到以后页面有可能嵌入到其他activity,或者把weex的渲染放入新建的WeexFragment。然后新建WeexActivity来引用该WeexFragment 。所有的单独页面的weex渲染都使用这个activity,非单独页面的使用weexFragment,这样新加页面时,无需重新注册activity。weex处理逻辑统一,方便管理,方便动态配置。通过统一跳转协议跳转到WeexActivity,通过intent传入两个参数url和h5。h5:用来降级的h5页面链接,当渲染失败时,会跳转到该h5页面
5、开始渲染js,失败后降级到h5
首先实例化WXSDKInstance2)注册的广播是DefaultBroadcastReceiver,可以可以参考weexteam里的AbsWeexActivity实现
然后讲一下渲染,支持本地js以及线上js
传入本地的存储地址时,先读取文件,然后同个Handler在UI线程渲染,如下:
渲染回调的实现,按需要处理即可,渲染成功后隐藏loading,view创建后添加view。渲染异常时降级跳转到h5。例如:
6、多个js在同个页面渲染
为了实现如图的tab,一开始在.we文件里使用tabbar组件,后来发现在Android机型适配上不够好。于是后来就将两个tab做成两个页面,生成两个js文件。首先渲染“我的订单.js”,生成如下的界面。然后点击“本店订单”时,调用自定义module里的接口loadPage,参数为h5的链接。三端实现接口loadPage,h5直接跳转,而iOS和Android通过h5链接从weex跳转配置里找到对应的js,重新渲染显示。下面具体做几点说明:1)定义Map<String, WXSDKInstance> wxsdkInstanceMap;来存储不同js的WXSDKInstance,定义Map<String,
View> viewMap来存储不同js渲染后的View。之所以要存储多个WXSDKInstance,是因为WXSDKInstance不能重复渲染,而且当WXSDKInstance
destory后,之前渲染的view里的内容也会被清空。注意在在页面destory时,记得把所有WXSDKInstance都destory就好了。
2)viewMap里的key对应页面的js。点击tab切换页面时,如对应的js已渲染,则直接取出view来显示。
3)上文提到的weex跳转配置,在以下的跳转规则里一同介绍。
二、App的跳转规则的weex支持方案设计
跳转规则如下图,如果看不清,可以到新页面放大查看,主要介绍一下两个配置参数:1)参数interceptUrlList可以动态配置需要拦截的h5链接,然后生成统一跳转地址
showjoyshop://page.sh/order
示例如下:
url:需要匹配的链接的正则表达式
v:最低版本支持
2)然后通过order在参数weexPages里查找对应的js信息,然后渲染。
示例如下:
对应统一跳转的 path
url:
需要渲染的js,
md5:
js文件的md5值用于校验,
h5:
渲染失败后的降级方案,
v:
最低支持的版本号
这样就达到了动态拦截,动态上线weex的目的。
三、js预加载方案
前面讲到为了加快weex打开时间,会预加载js,这里就介绍一下js预加载的实现。1)每次更新完配置文件,遍历,查看是否存在md5一致的page_xxx.js文件,如果不存在则更新.
2)下载完成后,保存格式为xxx.js,校验md5
相同的话,记录文件的最后修改时间;
不同的话,删除已下载文件,重新下载,重复校验流程。
3)支持统一跳转协议,page对应目前app端的统一跳转协议里的page,有必要的时候可以替换原来的native页面,解决native页面错误不能及时修复的问题。加载失败的话,打开h5页面。
4)每次打开指定页面的时候,先检查本地是否有对应page文件,再检验最后修改时间是否跟记录的一致
一致就加载
不一致就用线上url。
四、遇到的问题以及解决方法
问题一:上线后,发现在一些机型渲染失败,publicvoid onException(WXSDKInstance instance, String errCode, String msg)回调里,errCode返回wx_create_instance_error,msg返回createInstance
fail!
解决办法:将apk解压出来后,发现编译出了支持5种abi的包。然而libweexv8.so只在armeabi和x86里有,缺少对其它三种abi的支持,那么如果应用运行于arm64-v8a,x86_64,armeabi-v7a为首选abi的设备上时,就会加载失败了。其实arm64-v8a,armeabi-v7a,x86_64这三个abi,应用并不是必须要做支持,手机一般都会提供自动兼容。所以我们只要把对x86,
arm64-v8a,x86_64的支持去掉就可以。如下在主模块的build.gradle的android里的defaultConfig内添加如下内容:
问题二:OkHttpAdapter里调用onHttpFinish出现解析异常,日志如下:
解决方法:在.we文件里链接以及请求地址使用相对地址,h5页面自动选择该页面使用的域名,而在iOS和Android都做拦截处理,根据当前环境添加相应的域名。
参考链接:
https://github.com/weexteam/
http://weex-project.io/doc/
https://github.com/alibaba/weex/
相关文章推荐
- Unity 接入应用宝 SDK 即 YSDK 过程中遇到的问题记录 20180302
- 删除一条记录的过程
- 传真服务器开发 三页传真过程全记录(日志形式)
- 通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录
- QQ聊天记录保护器制作全过程
- Ubuntu 6.06,硬盘安装,简单优化,ati驱动及xgl安装全过程记录
- 工程开始,记录一下工程的全过程
- 记录hibernate 3学习过程中的报错(未完成)
- 全程记录:今天尝试安装SharePoint Server 2007过程 ,安装成功了,但是开始使用碰到权限问题,应该算是BUg吧
- QQ聊天记录保护器制作全过程
- 修改后的存储过程``哈哈``可以输出总记录数 总页数
- :[百万级]通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录
- FreeBSD网站平台建设全过程(二、接入Internet并配制代理服务)
- 入侵XXX学校教务管理系统过程记录
- 记录hibernate 3学习过程中的报错(未完成)
- 记录一下自己利用smtp和jmail发邮件的过程
- 通用存储过程.查找删除非唯一的记录
- 通用存储过程.分页存储过程..返回指定返回条数、指定页数的记录
- 存储过程结合bcp--将数据库记录导出成SQL脚本的形式.
- 我的FreeBSD5.4安装配置过程笔记录(新手参考)第1/5页