科伦文档二:

经过文档一的描述,我们已经可以把app的生命周期传递到js。只要app在调用js桥的方法的时候,传了name属性,对应的方法就可以通过js的map正确的传递到对应js页面。这里我们详细描述一下,app的生命周期是如何精准的传递到js的,了解后我们就能明白js是如何传递到app对应的页面的。


name页面的名字属性是核心:

首先,一个原生页面就一定有一个对应的js页面。比如有注册zhuce.activity这个原生页面,就有一个zhuce.js页面与之对应。他们之间的桥梁是name这个属性。

zhuce.activity 注册页面在页面加载后,立马调用了js的onLoad属性,然后js在全局收到了onLoad这个action,此时js取出name = zhuce,发现在原生有一个叫zhuce的页面onLoad了,此时js会立马找到一个叫Zhuce的js的页面类立马实例化,实例化后得到zhuce的js对象,先放到js的pageMaps中,以下是js的核心代码:

let action = json.action  //因为这里action=zhuce,我下面就简单的按zhuce页面来写

let page_name = json.name // 这里得到zhuce

let PageClassStr =  page_name.upper() //首字母大写,转为Zhuce

if(action == "onLoad"){

    let page_obj = eval('new PageClassStr()') //根据Zhuce动态运算得到Zhuce页面的对象实例

    window.pageMaps[page_name] =  page_obj  //注册页面放到全局的map中,key就是zhuce

}

好了,现在可以把app传递过来的生命周期全部转接到注册页面了。

if(page_obj[action] != null){

    page_obj[action] (json)  //如果page_obj 这个页面实现了action方法,就传json参数并调用

}


生命周期封装:

很明显,页面会创建就一定有销毁。当js收到app传递过来onUnload方法,说明这个原生页面被销毁了,js也会干掉对应的js对象。

所以保证原生页面的生命周期正确被调用很重要。同时,原生页面要正确的被释放,比如从我的页面打开登录页面,然后点了登录返回,此时登录页面应该被销毁并触发onUnload方法,这很重要,这样才能确保资源被正确的释放。

总结一下:

在BaseActivity和BaseFragment封装中,一定要正确触发onLoad, onShow, onHide, onUnload。


全局一个桥,如何区分页面的?

了解了上面的js的操作逻辑,其实实现对应的原生页面也不难了。在正式说明之前,需要说明一个重要的约定,即任何一个页面都一定有一个具体的子类。比如登录页面一定有一个DengluActivity,我们不是动态从父类实例化的,我们是从一个确定的子类来的,这非常重要。后面说到原因。因为每个页面可能未来操作不太一样,而且每个页面的数据事件都是在子类各自实现的。

首先在原生需要定义一个map,这个map主要实现两个功能:

(1)给一个页面的page字符串,需要知道对应页面的具体的类名,用于push的时候动态反射实例化。

(2)如果page对应的页面实例化后,需要再保存对应的存在的页面对象。

因为安卓tab的原因,我们设计了BasePageInterface接口来统一BaseActivity和BaseFragment. 所以这个map我们这样设计:

(1)首先map放哪,我觉得应该可以放到静态变量中,ios因为只有一个类,我放到了BaseActivity中。假设你放到全局变量中:pageMap

(2)大概长什么样子?

let pageMap: [String: BasePageInterface] = { 

    "denglu": {

            "Class": "DengluActivity",//登录页面的类名,用来反射实例化对象

            "instance": null, //BasePageInterface类型,登录页面的实例化后的对象

    } ,

   //其他页面   

}

有了这个page后,虽然全局只有一个桥,但js用页面的name可以找到精准的对应的页面。



现在我们再回到封装中,以BaseActivity为例(BaseFragment同理),页面的初始化的时候一定要完善name字段,每个页面都有name属性。

在BaseActivity的onLoad里面

pageMap[this.name].instance = this //当前页面已经是一个实例,指针放到map中。

js("onLoad") //调用js的onLoad,上一篇已经说明过了


很明显,有一个对称的操作:

在BaseActivity的onUnload里面

pageMap[this.name].instance = null //当前页面已经销毁,从map中移除实例

js("onUnload") //调用js的onUnload,上一篇已经说明过了,


初始化tab需要初始化完善一些map需要的信息:

好了。现在我们创建4个tab页面的时候,这4个tab页面一启动就存在了,所以我们需要手动完善下map:

pageMap["shouye"].instance = shouye //其他4个页面同理

app一启动,有默认有5个instance存在于map中了,其他页面基本是封装好后,js来自动化管理控制了。假设没操作这步,很明显js在使用name找页面的时候是找不到对应的tab页面的。


技术实战:

push协议:

协议名:push

参数: 

{

    "name": "denglu"  //push新页面的name,app需要根据name取出Class实例化

    "options": "", //json格式的参数,后面细说

}

push的时候,app需要根据name取出Class实例化,然后打开新页面,可以知道,因为是封装的原因,新页面创建后,在内部onLoad会自动把自己放到pageMap中。


当然我们要触发push依赖点击事件,这个是下一篇文件VM表单控件触发的说完才能触发push,不过可以先写push这个方法。我们循循渐进。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容