动态化

Q:Android与JS交互?

Android调用js代码

  • 通过WebView的loadUrl()
//会触发页面刷新
mWebView.loadUrl("javascript:callJS()");
  • 通过WebView的evaluateJavascript()
//不会触发界面刷新,可以获取到返回结果
mWebView.evaluateJavascript"javascript:callJS()", new ValueCallback<String>() {
    @Override
    public void onReceiveValue(String value) {
        //此处为 js 返回的结果
    }
});

JS调用Android代码

  • 通过WebView的addJavascriptInterface()进行对象映射
//参数1:Javascript对象名 参数2:Java对象名
mWebView.addJavascriptInterface(new AndroidtoJs(), "test");//AndroidtoJS类对象映射到js的test对象
  • 通过 WebViewClient 的shouldOverrideUrlLoading ()方法回调拦截 url
  • 通过 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回调拦截JS对话框alert()、confirm()、prompt() 消息

Q:J2V8引擎

V8.createV8Runtime();//启动v8
v8.executeVoidScript(jsonJs);//读取js文件的string内容,将其注入到js引擎中
v8.registerJavaMethod(voidCallback,registName);//是否需要注册方法回调
v8.executeStringFunction(name, array);//执行对应方法

Q:一个JSRuntime如何区分多个js环境?

在js的全局环境中设置唯一标识defaultObject+index

Q:设计一个动态化框架需要考虑什么

  1. 通信方式 js调native 桥,通过JNI获取java中的方法,然后调用V8或者其它引擎的相关方法进行绑定 native调js 调用V8或者其他引擎的相关方法进行调用
  2. 性能
    bundle加载
        MRN:
            1.拆包,meta.json中定义dependency,开始时只加载主包,然后加载业务包
            2.包体积缩小,一是打包时引入Tree Shaking技术,裁剪无用代码,二是抽出公用模块
            3.懒加载
    首屏加载
    渲染性能
        MRN:
            1.提前加载业务bundle,执行到业务时只需要进行短时间的渲染操作,V8在完成代码编译后会以字节码的形式产出CodeCache并可将其序列化到磁盘上在下次编译时可以提供CodeCache会大大缩短代码的解析和编译时间
            2.分步渲染,在渲染界面上打上标记,加载优先级高的界面
            3.白屏优化:通过MTFlexbox提前生成native界面,作为loadingView,然后RN渲染完成后进行替换
    长列表
        MRN:
            1.js层接收native即将消失事件通知,重新构建shandowtree
            2.native层在快速滑动时不渲染数据,使用空白container渲染数据,待js数据返回后再渲染到item上
    模块级or页面级
        MRN:
            1.使用Redux进行数据传递
    js复用
    线程管理
    引擎管理
        MRN:
            PriorityQueue维护了一个大小为4的引擎队列,根据最后使用时间排序,当有对应bundle引擎存在时,直接使用,默认回收时间2分钟
        Mach:
            
    跳转管理
       调用Native方法,通过Router进行跳转