新聞中心
想了解更多內容,請訪問:

創(chuàng)新互聯(lián)建站服務項目包括清澗網(wǎng)站建設、清澗網(wǎng)站制作、清澗網(wǎng)頁制作以及清澗網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構等提供互聯(lián)網(wǎng)行業(yè)的解決方案,清澗網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到清澗省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!
和華為官方合作共建的鴻蒙技術社區(qū)
https://harmonyos.
在講解ActiveData實現(xiàn)原理之前,我們有必要先了解一下兩個重要的類Lifecycle以及DataObserver,這兩個類在ActiveData整個運行過程中扮演了非常重要的角色。
- Lifecycle提供了觀察Ability和AbilitySlice的生命周期能力
- DataObserver通過持有一個Lifecycle對象來觀察Ability或者AbilitySlice的生命周期變化,同時DataObserver還允許ActiveData觀察其生命周期變化,因此DataObserver和ActiveData相互觀察,DataObserver觀察ActiveData的數(shù)據(jù)變化,ActiveData觀察DataObserver的生命周期變化。
ActiveData作用和特點
ActiveData是一個具有感知生命周期能力變化的數(shù)據(jù)通知類組件,非常適合在一些對數(shù)據(jù)同步性較高的場景下使用,它具有以下三個特點。
基于觀察者模式:
ActiveData是一個持有可被觀察數(shù)據(jù)的類,ActiveData需要一個觀察者對象,一般是DataObserver類的具體實現(xiàn)。
感知生命周期:
ActiveData具有生命周期感知能力,目前ActiveData具有兩種通知模式,一種是Ability/AbilitySlice生命周期是活躍(ACTIVE)狀態(tài)時才更新數(shù)據(jù),另一種是Ability/AbilitySlice生命周期處于任何存活狀態(tài)(即只要沒有被銷毀)都可以更新數(shù)據(jù)。
自動解除數(shù)據(jù)訂閱:
ActiveData必須配合實現(xiàn)了Lifecycle的對象使用。當Ability/AbilitySlice被銷毀(STOP狀態(tài))后,會自動解除訂閱,這在一定程度上可以避免內存泄漏等問題。
實踐
1.基礎用法
- public class MainAbilitySlice extends AbilitySlice {
- private ActiveData
activeData; - private Text mText;
- private final DataObserver
dataObserver = new DataObserver () { - @Override
- public void onChanged(String s) {
- mText.setText(s);
- }
- };
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- activeData = new ActiveData<>();
- dataObserver.setLifecycle(getLifecycle());
- mText = (Text) findComponentById(ResourceTable.Id_text_helloworld);
- subscribe();
- }
- private void subscribe() {
- activeData.addObserver(dataObserver, true);
- }
- @Override
- public void onActive() {
- super.onActive();
- activeData.setData("New Hello World");
- }
- }
運行之后的截圖:
從運行結果可以看出,setData調用后會立即觸發(fā)onChanged回調方法
2.主線程手動調用
- // 添加如下代碼測試DataObserver的onChanged方法是否會執(zhí)行
- findComponentById(ResourceTable.Id_button)
- .setClickedListener(component -> activeData.setData("I Love China"));
運行結果如下:
從運行結果我們可以看到,onChanged方法會一直觸發(fā),并不會因為值相同而不執(zhí)行,雖然暫時看不了鴻蒙源碼,但我們可以大膽猜測,鴻蒙底層維護了一個類似于版本號的標記,每次setData,該標記會自動+1,從而通過此版本號來判斷data是否有變化,進而決定是否觸發(fā)onChanged回調方法。
3.子線程調用
- @Override
- public void onActive() {
- super.onActive();
- new Thread(() -> activeData.setData("New Hello World")).start();
- }
4.運行后發(fā)現(xiàn)沒有問題,可以正常調用,說明setData方法可以在子線程調用。
- public class MainAbilitySlice extends AbilitySlice {
- private ActiveData
activeData; - private ActiveData
activeData2; - private Text mText;
- private final DataObserver
dataObserver = new DataObserver () { - @Override
- public void onChanged(String s) {
- mText.setText(s);
- System.out.println("ActiveData:---onChange:"+s);
- }
- };
- private final DataObserver
dataObserver2 = new DataObserver () { - @Override
- public void onChanged(String s) {
- mText.setText(s);
- System.out.println("ActiveData:---onChange:"+s);
- }
- };
- @Override
- public void onStart(Intent intent) {
- super.onStart(intent);
- super.setUIContent(ResourceTable.Layout_ability_main);
- activeData = new ActiveData<>();
- activeData2 = new ActiveData<>();
- dataObserver.setLifecycle(getLifecycle());
- dataObserver2.setLifecycle(getLifecycle());
- mText = (Text) findComponentById(ResourceTable.Id_text_helloworld);
- findComponentById(ResourceTable.Id_button)
- .setClickedListener(component -> activeData.setData("I Love China"));
- findComponentById(ResourceTable.Id_addObserver_true).setClickedListener(component -> {
- System.out.println("ActiveData:-------------");
- Intent intent1 = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId("")
- .withBundleName(getBundleName())
- .withAbilityName(SecondAbility.class.getName())
- .build();
- intent1.setOperation(operation);
- startAbility(intent1);
- // 此處是為了驗證Ability在inActive狀態(tài)的值的變化情況
- new EventHandler(EventRunner.getMainEventRunner()).postTask(() -> activeData.setData("New Hello World"), 2000);
- });
- findComponentById(ResourceTable.Id_addObserver_false).setClickedListener(component -> {
- System.out.println("ActiveData:-------------");
- Intent intent1 = new Intent();
- Operation operation = new Intent.OperationBuilder()
- .withDeviceId("")
- .withBundleName(getBundleName())
- .withAbilityName(SecondAbility.class.getName())
- .build();
- intent1.setOperation(operation);
- startAbility(intent1);
- // 此處是為了驗證Ability在inActive狀態(tài)的值的變化情況
- new EventHandler(EventRunner.getMainEventRunner()).postTask(() -> activeData2.setData("New Hello World"), 2000);
- });
- subscribe();
- }
- private void subscribe() {
- activeData.addObserver(dataObserver, true);
- activeData2.addObserver(dataObserver, false);
- }
- @Override
- public void onActive() {
- super.onActive();
- System.out.println("ActiveData:---onActive");
- }
- @Override
- protected void onInactive() {
- super.onInactive();
- System.out.println("ActiveData:---onInactive");
- }
- @Override
- protected void onBackground() {
- super.onBackground();
- System.out.println("ActiveData:---onBackground");
- }
- @Override
- public void onForeground(Intent intent) {
- super.onForeground(intent);
- System.out.println("ActiveData:---onForeground");
- }
- }
運行效果如下:
從以上運行結果,可以看出addObserver(dataObserver, true/false)方法的特點,當為true是表示無論Ability/AbilitySlice處于任何生命周期狀態(tài),均會觸發(fā)onChanged回調方法,當為false時表示Ability/AbilitySlice只有處于ACTIVE狀態(tài)時才會觸發(fā)onChanged方法。
總結
- ActiveData內部是依靠Lifecycle來感知組件的生命周期,從而可以避免內部泄漏
- 開發(fā)者無需維護observer對象,當Ability/AbilitySlice被銷毀時,相關聯(lián)的observer會被自動移除
- 當Ability/AbilitySlice處于活躍(ACTIVE)狀態(tài)時,當ActiveData數(shù)據(jù)源發(fā)生變化時onChanged方法會立即觸發(fā),去更新UI或者執(zhí)行我們想要的任何操作
- setData方法可在任意線程中去調用,開發(fā)者無需關心調用者是否在主線程中
- setData方法即使設置同樣的數(shù)據(jù)對象,onChanged方法仍然會被觸發(fā)
想了解更多內容,請訪問:
和華為官方合作共建的鴻蒙技術社區(qū)
https://harmonyos.
分享名稱:ActiveData在HarmonyOS中的原理分析和運用
文章出自:http://www.fisionsoft.com.cn/article/cdsjooi.html


咨詢
建站咨詢
