鴻蒙開源第三方組件-B站開源彈幕庫引擎的遷移(下)
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)
前言
本期,我們將以彈幕庫為例,讓大家了解開源三方件是如何從安卓遷移到鴻蒙的!
看完本篇內(nèi)容,你不僅能夠明白"我們是如何遷移彈幕庫"的,還可以自己嘗試遷移感興趣的安卓開源三方件!
本次的內(nèi)容包含兩個(gè)部分,主要為大家講解:開源三方件遷移的本質(zhì)是什么、如何完成開源三方件的遷移。
1、本質(zhì)
三方件是一個(gè)向下使用安卓/鴻蒙的SDK方法,完成特定功能,向上為用戶提供統(tǒng)一的接口,供用戶調(diào)用的中間件。
想將一個(gè)安卓的三方件遷移至鴻蒙,要做的是:向上的接口保持不變(功能輸出和接口相同,方便用戶調(diào)用),向下調(diào)用的方法由安卓轉(zhuǎn)為鴻蒙,也就是從使用安卓的底層SDK提供的方法變?yōu)槭褂螟櫭傻牡讓覵DK提供的方法。下圖以彈幕庫為例子解釋了這個(gè)過程:
圖1:彈幕庫組件遷移示意圖
原始彈幕庫組件版本(https://github.com/bilibili/DanmakuFlameMaster)中,我們點(diǎn)開其中任意幾個(gè)文件,查看其import信息:
圖2:DrawHandler.java
可以看到,文件中使用了大量的"import android.xxxx"的包名,表明組件包含了大量安卓自身的API調(diào)用,來實(shí)現(xiàn)特定功能,因此我們要做的是通過調(diào)用鴻蒙的API來實(shí)現(xiàn)相同的功能,由于安卓和鴻蒙底層架構(gòu)及通信機(jī)制等各方面的不同,所以此處并不是簡單地逐一替換關(guān)系。
2、方法
在實(shí)際的遷移過程中,安卓和鴻蒙的包名、類名和方法名都可能會(huì)不同。根據(jù)遷移的難易程度,可以分為以下四種情況。
1. 包名不同,類名相同
有一些比較簡單的類,它在安卓和鴻蒙中僅僅是包名發(fā)生了變化,類名、接口和方法沒有變化,像這樣的類,我們只要在文件中進(jìn)行import后的包名替換即可,如下圖所示。
2. 類名不同,方法名相同
有一些類,它在安卓和鴻蒙中包名和類名都發(fā)生了變化,接口沒有變化,如下圖所示。
圖4:源碼示例
此時(shí)需要翻閱安卓和鴻蒙的開發(fā)文檔,以未變化的方法名為線索進(jìn)行查找,對(duì)同功能的類進(jìn)行匹配。
安卓:
https://developer.android.google.cn/reference/packages
鴻蒙:
https://developer.harmonyos.com/cn/docs/documentation/doc-references/overview-0000001054518434
像上面說的兩種簡單情況,在實(shí)際的遷移過程中幾乎是不會(huì)出現(xiàn)的,在鴻蒙系統(tǒng)中也只有很少一部分基礎(chǔ)庫所提供的接口是與安卓相似的,其他部分的庫與安卓相差甚遠(yuǎn)。
3. 包名、類名和方法完全不同
此時(shí),對(duì)于安卓中調(diào)用的接口,無法直接在鴻蒙中找到與之對(duì)應(yīng)的。需要我們具有一定的源碼閱讀能力,充分理解安卓接口的功能實(shí)現(xiàn)和模塊劃分(媒體、權(quán)限、視圖...),再去鴻蒙相應(yīng)的模塊查找與之相似的使用方法。
圖五:源碼示例
這里就是一個(gè)典型的例子,注釋方法為安卓方法,下面方法是鴻蒙方法??梢钥吹皆赗ECT(Class:RectFloat)這個(gè)變量的初始化中就出現(xiàn)了不一樣的使用方式。
4. 功能重寫
前三種方法,接口在安卓和鴻蒙間存在對(duì)應(yīng)關(guān)系,我們只需要理解、查找和匹配。在功能實(shí)現(xiàn)方式完全不同的情況下,需要我們具有一定的代碼閱讀能力和重寫能力,在鴻蒙中對(duì)相應(yīng)功能進(jìn)行重寫。以彈幕庫為例:
---多線程通信:
安卓和鴻蒙的多線程通信機(jī)制類似,但是使用方法相差較大。
解決方法:功能重寫。
圖6:安卓中的多線程通信邏輯
圖7:鴻蒙中的多線程通信邏輯
可以看到兩個(gè)版本的多線程通信的大體邏輯都是相同的,兩個(gè)Thread想要進(jìn)行通信,都需要四個(gè)步驟:
1.通信發(fā)起方需要構(gòu)建(或?qū)嵗?一個(gè)結(jié)構(gòu)體(或類)來進(jìn)行事件的傳遞(并攜帶信息本身)。
2.這個(gè)攜帶著信息的結(jié)構(gòu)化對(duì)象到了信息接收方后,會(huì)首先進(jìn)入一個(gè)消息隊(duì)列進(jìn)行等待處理。
3.當(dāng)結(jié)構(gòu)化對(duì)象被從隊(duì)列中取出后,會(huì)進(jìn)入消息接收方的信息處理邏輯。
4.處理完成后消息接收方會(huì)生成一個(gè)反饋(回調(diào)),將處理結(jié)果反饋給消息發(fā)送方。
但是我們可以細(xì)心觀察一下,安卓和鴻蒙的處理細(xì)節(jié)是有很大差異的。在安卓上使用這個(gè)機(jī)制的時(shí)候,需要先new一個(gè)HandlerThread,然后new一個(gè)looper,接著將他們綁定在一起,使用Thread.start才能讓跑起來,實(shí)現(xiàn)消息隊(duì)列發(fā)送及取出消息處理的功能。在鴻蒙上則不用如此麻煩,只需要new一個(gè)eventrunner就可以實(shí)現(xiàn)同樣的功能,如下圖所示。
圖8:源碼示例
---UI部分
由于鴻蒙UI的構(gòu)建方式和安卓存在很多差異,導(dǎo)致無法直接通過替換接口的方式來實(shí)現(xiàn)與安卓相對(duì)應(yīng)的UI能力,這就需要進(jìn)一步將對(duì)應(yīng)的功能基于鴻蒙的構(gòu)建方式進(jìn)行重寫。
解決方法:功能重寫
以O(shè)HOSP/AOSP自定義繪制能力對(duì)比為例:
圖9:OHOSP/AOSP自定義繪制能力對(duì)比圖
安卓在繪制時(shí),直接調(diào)用draw()方法,將canvas繪制到view上,鴻蒙則需對(duì)當(dāng)前的component添加drawtask,重寫drawtask里的ondraw方法,完成對(duì)canvas的繪制。
安卓實(shí)現(xiàn)如下:
圖10:安卓實(shí)現(xiàn)自定義繪制能力
鴻蒙:
圖11:鴻蒙實(shí)現(xiàn)自定義繪制能力
51CTO和華為官方合作共建的鴻蒙技術(shù)社區(qū)