目前市面上存在以下几种动态化的方案
l LUA
l 插件化
l WebView
l React Native
l LUAView
l Weex
l 热补丁
其中:
l 热补丁的修复能力突出,无论目前存在的那种热补丁形式,都会依赖于原始版本,和目标版本进行查分别叫,无法实现真正的动态化,而且随着差异化的增加,风险越来越高,
l WebView的动态化能力简单,三端统一便利,但是性能是主要的瓶颈,无法完成全部功能的替换。
l LUA动态化简单,但是原始框架过于简单,可以实现简单的动态化,但是对于复杂的Android动态化功能,需要完全自己封装一套中间件,工作量大,难度高。
l 插件化,我们已经非常熟悉,无论使用还是设计,都不再需要花费时间来进行调研,只需要对比就好了。
上面几个由于存在无法避免的问题,所以我们主要对LUAView,Weex, React Native进行调研,方便我们日后进行扩展,达到知己知彼,快速扩展的效果。
LuaView的原理及使用
简介:LuaView并非是Lua,而是使用一种全新的解析器来解析Lua语言(用的开源框架luaj)。
首先抛弃LuaView的代码实现,设想我们自己设计一款代码解析器。
麻雀虽小,五脏具全,Lua的整体设计思路也是围绕着这几个模块进行的。
首先我们看一个简单的Lua文件
local screenWidth,screenHeight = System.screenSize()
-- Test Label
local label = Label()
label.text(System.ios() and "iOS" or "Android")
label.textColor(0x000000)
label.frame(0, 0, screenWidth, screenHeight)
label.textAlign(TextAlign.CENTER)
-- Test Button
local btn = Button()
btn.size(200, 200)
btn.text("Click Me")
btn.backgroundColor(0xff0000)
btn.callback(function()
Alert("Hello LuaView")
end)
其实看源码我们很容易发现实际上就是解析,显示的流程,流程很简单,主要是代码细节写的很牛逼,简单的流程如下。
所以我们综上所诉,LuaView可以实现所有Androidapi上大部分的功能,不止是view的问题,无非就是扩展的问题,
所以我们实验以下我们的假设,我们自定义语法
t = TT()
t.show(dddd)
显示一个toast
首先加入binder
public class UITTBinderextends BaseFunctionBinder {
public UITTBinder() {
super("TT");
}
@Override
public Class<? extends LibFunction> getMapperClass() {
return UITTMethodMapper.class;
}
@Override
public LuaValue createCreator(LuaValue env,final LuaValue metaTable) {
return new BaseVarArgCreator(env.checkglobals(),metaTable, getMapperClass()) {
@Override
public LuaValue createUserdata(Globals globals,LuaValue metaTable, Varargs varargs) {
return new TTToast(globals, metaTable, varargs);
}
};
}
}
然后创建代理对象,
public class TTToastextends BaseUserdata {
public TTToast(Globals globals, LuaValue metaTable,Varargs varargs) {
super(globals, metaTable, varargs);
}
}
然后添加Toast的所有方法
public class UITTMethodMapper<Uextends TTToast> extends BaseMethodMapper<U> {
private static final String TAG = "UIToastMethodMapper";
private static final String[]sMethods = newString[]{
"show"//0
};
@Override
public List<String> getAllFunctionNames() {
return mergeFunctionNames(TAG,super.getAllFunctionNames(), sMethods);
}
@Override
public Varargs invoke(intcode, U target, Varargs varargs) {
final int optcode = code -super.getAllFunctionNames().size();
switch (optcode) {
case 0:
return show(target, varargs);
}
return super.invoke(code, target, varargs);
}
//--------------------------------------- API--------------------------------------------------
/**
* show a toast
*
* @param view
* @param varargs
* @return
*/
public LuaValue show(Uview, Varargs varargs) {
final CharSequence text = LuaViewUtil.getText(varargs.optvalue(2,NIL));
return ToastUtil.show(getContext(),text);
}
}
添加这几个类就完成了,下一步我们需要在初始化的适合注册binder
globals.tryLazyLoad(new UITTBinder());
这样就完成了我们自定义TT字段显示Toast的功能。
在lua文件中实验一下,成功。
总结:综上所述,LuaView的实现原理还是通过翻译之后,执行api的代码,所以效率来看应该是很高的,只是有一些在反射,和代码逻辑调用的时候,多消耗了一些内存和效率,但是在绘制等问题上,完全是WebView无法比拟的,使用户体验可以接受的动态化方案。
当然缺点也是有的,除去上面所说的一些内存和效率问题外,主要的还是在项目构建的时候,替换的工作量是个不小的问题,需要将项目拆分,解耦,决定哪些功能使用luaView,完全从写,是一个不小的工作量,
而且扩展也是个不小的工作量,他没有办法项Lua一样,直接调用Android api,而是完全是自己封装的,所以需要扩展的化,就要自己封装,虽然架构比较清晰,扩展方便,但也是需要不小的工作量的。