科倫文檔二:

經(jīng)過(guò)文檔一的描述,我們已經(jīng)可以把a(bǔ)pp的生命周期傳遞到j(luò)s。只要app在調(diào)用js橋的方法的時(shí)候,傳了name屬性,對(duì)應(yīng)的方法就可以通過(guò)js的map正確的傳遞到對(duì)應(yīng)js頁(yè)面。這里我們?cè)敿?xì)描述一下,app的生命周期是如何精準(zhǔn)的傳遞到j(luò)s的,了解后我們就能明白js是如何傳遞到app對(duì)應(yīng)的頁(yè)面的。


name頁(yè)面的名字屬性是核心:

首先,一個(gè)原生頁(yè)面就一定有一個(gè)對(duì)應(yīng)的js頁(yè)面。比如有注冊(cè)zhuce.activity這個(gè)原生頁(yè)面,就有一個(gè)zhuce.js頁(yè)面與之對(duì)應(yīng)。他們之間的橋梁是name這個(gè)屬性。

zhuce.activity 注冊(cè)頁(yè)面在頁(yè)面加載后,立馬調(diào)用了js的onLoad屬性,然后js在全局收到了onLoad這個(gè)action,此時(shí)js取出name = zhuce,發(fā)現(xiàn)在原生有一個(gè)叫zhuce的頁(yè)面onLoad了,此時(shí)js會(huì)立馬找到一個(gè)叫Zhuce的js的頁(yè)面類立馬實(shí)例化,實(shí)例化后得到zhuce的js對(duì)象,先放到j(luò)s的pageMaps中,以下是js的核心代碼:

let action = json.action ?//因?yàn)檫@里action=zhuce,我下面就簡(jiǎn)單的按zhuce頁(yè)面來(lái)寫(xiě)

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

let PageClassStr = ?page_name.upper() //首字母大寫(xiě),轉(zhuǎn)為Zhuce

if(action == "onLoad"){

????let page_obj = eval('new?PageClassStr()') //根據(jù)Zhuce動(dòng)態(tài)運(yùn)算得到Zhuce頁(yè)面的對(duì)象實(shí)例

? ? window.pageMaps[page_name] = ?page_obj ?//注冊(cè)頁(yè)面放到全局的map中,key就是zhuce

}

好了,現(xiàn)在可以把a(bǔ)pp傳遞過(guò)來(lái)的生命周期全部轉(zhuǎn)接到注冊(cè)頁(yè)面了。

if(page_obj[action] != null){

? ??page_obj[action] (json) ?//如果page_obj 這個(gè)頁(yè)面實(shí)現(xiàn)了action方法,就傳json參數(shù)并調(diào)用

}


生命周期封裝:

很明顯,頁(yè)面會(huì)創(chuàng)建就一定有銷毀。當(dāng)js收到app傳遞過(guò)來(lái)onUnload方法,說(shuō)明這個(gè)原生頁(yè)面被銷毀了,js也會(huì)干掉對(duì)應(yīng)的js對(duì)象。

所以保證原生頁(yè)面的生命周期正確被調(diào)用很重要。同時(shí),原生頁(yè)面要正確的被釋放,比如從我的頁(yè)面打開(kāi)登錄頁(yè)面,然后點(diǎn)了登錄返回,此時(shí)登錄頁(yè)面應(yīng)該被銷毀并觸發(fā)onUnload方法,這很重要,這樣才能確保資源被正確的釋放。

總結(jié)一下:

在BaseActivity和BaseFragment封裝中,一定要正確觸發(fā)onLoad, onShow, onHide, onUnload。


全局一個(gè)橋,如何區(qū)分頁(yè)面的?

了解了上面的js的操作邏輯,其實(shí)實(shí)現(xiàn)對(duì)應(yīng)的原生頁(yè)面也不難了。在正式說(shuō)明之前,需要說(shuō)明一個(gè)重要的約定,即任何一個(gè)頁(yè)面都一定有一個(gè)具體的子類。比如登錄頁(yè)面一定有一個(gè)DengluActivity,我們不是動(dòng)態(tài)從父類實(shí)例化的,我們是從一個(gè)確定的子類來(lái)的,這非常重要。后面說(shuō)到原因。因?yàn)槊總€(gè)頁(yè)面可能未來(lái)操作不太一樣,而且每個(gè)頁(yè)面的數(shù)據(jù)事件都是在子類各自實(shí)現(xiàn)的。

首先在原生需要定義一個(gè)map,這個(gè)map主要實(shí)現(xiàn)兩個(gè)功能:

(1)給一個(gè)頁(yè)面的page字符串,需要知道對(duì)應(yīng)頁(yè)面的具體的類名,用于push的時(shí)候動(dòng)態(tài)反射實(shí)例化。

(2)如果page對(duì)應(yīng)的頁(yè)面實(shí)例化后,需要再保存對(duì)應(yīng)的存在的頁(yè)面對(duì)象。

因?yàn)榘沧縯ab的原因,我們?cè)O(shè)計(jì)了BasePageInterface接口來(lái)統(tǒng)一BaseActivity和BaseFragment. 所以這個(gè)map我們這樣設(shè)計(jì):

(1)首先map放哪,我覺(jué)得應(yīng)該可以放到靜態(tài)變量中,ios因?yàn)橹挥幸粋€(gè)類,我放到了BaseActivity中。假設(shè)你放到全局變量中:pageMap

(2)大概長(zhǎng)什么樣子?

let pageMap: [String: BasePageInterface] = {?

? ? "denglu": {

? ? ? ? ? ? "Class": "DengluActivity",//登錄頁(yè)面的類名,用來(lái)反射實(shí)例化對(duì)象

? ? ? ? ? ? "instance": null, //BasePageInterface類型,登錄頁(yè)面的實(shí)例化后的對(duì)象

????} ,

? ?//其他頁(yè)面 ??

}

有了這個(gè)page后,雖然全局只有一個(gè)橋,但js用頁(yè)面的name可以找到精準(zhǔn)的對(duì)應(yīng)的頁(yè)面。



現(xiàn)在我們?cè)倩氐椒庋b中,以BaseActivity為例(BaseFragment同理),頁(yè)面的初始化的時(shí)候一定要完善name字段,每個(gè)頁(yè)面都有name屬性。

在BaseActivity的onLoad里面

pageMap[this.name].instance = this //當(dāng)前頁(yè)面已經(jīng)是一個(gè)實(shí)例,指針?lè)诺絤ap中。

js("onLoad") //調(diào)用js的onLoad,上一篇已經(jīng)說(shuō)明過(guò)了


很明顯,有一個(gè)對(duì)稱的操作:

在BaseActivity的onUnload里面

pageMap[this.name].instance = null //當(dāng)前頁(yè)面已經(jīng)銷毀,從map中移除實(shí)例

js("onUnload") //調(diào)用js的onUnload,上一篇已經(jīng)說(shuō)明過(guò)了,


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

好了?,F(xiàn)在我們創(chuàng)建4個(gè)tab頁(yè)面的時(shí)候,這4個(gè)tab頁(yè)面一啟動(dòng)就存在了,所以我們需要手動(dòng)完善下map:

pageMap["shouye"].instance = shouye //其他4個(gè)頁(yè)面同理

app一啟動(dòng),有默認(rèn)有5個(gè)instance存在于map中了,其他頁(yè)面基本是封裝好后,js來(lái)自動(dòng)化管理控制了。假設(shè)沒(méi)操作這步,很明顯js在使用name找頁(yè)面的時(shí)候是找不到對(duì)應(yīng)的tab頁(yè)面的。


技術(shù)實(shí)戰(zhàn):

push協(xié)議:

協(xié)議名:push

參數(shù):?

{

? ? "name": "denglu" ?//push新頁(yè)面的name,app需要根據(jù)name取出Class實(shí)例化

? ? "options": "", //json格式的參數(shù),后面細(xì)說(shuō)

}

push的時(shí)候,app需要根據(jù)name取出Class實(shí)例化,然后打開(kāi)新頁(yè)面,可以知道,因?yàn)槭欠庋b的原因,新頁(yè)面創(chuàng)建后,在內(nèi)部onLoad會(huì)自動(dòng)把自己放到pageMap中。


當(dāng)然我們要觸發(fā)push依賴點(diǎn)擊事件,這個(gè)是下一篇文件VM表單控件觸發(fā)的說(shuō)完才能觸發(fā)push,不過(guò)可以先寫(xiě)push這個(gè)方法。我們循循漸進(jìn)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容