自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

元數(shù)據(jù)綁定系列(二):元數(shù)據(jù)綁定進階

開發(fā) 前端
通過codelbs代碼的學習,這一篇我們更深入思考一下。不然,對于元數(shù)據(jù)綁定我們永遠只是停留在使用工具的重復勞動階段。

[[420940]]

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區(qū)

https://harmonyos.51cto.com

先上源碼:

喵叔catuncle / TestMetaDataBinding(主程序)

喵叔catuncle / TestDataCenter(配合主程序演示跨進程、跨設備特性)

demo截圖

上一篇元數(shù)據(jù)綁定系列(一):元數(shù)據(jù)綁定的使用,算是元數(shù)據(jù)綁定入門。通過codelbs代碼的學習,這一篇我們更深入思考一下。不然,對于元數(shù)據(jù)綁定我們永遠只是停留在使用工具的重復勞動階段。

代碼項目結構

元數(shù)據(jù)綁定系列(二):元數(shù)據(jù)綁定進階-鴻蒙HarmonyOS技術社區(qū)
  • entry:程序入口(主程序,自定義元數(shù)據(jù)類HelloUiMetaData也放在這個module)
  • dataability:請忽略這個名字,最開始放的是AlarmClock的數(shù)據(jù)綁定。后來rdb作為數(shù)據(jù)源要和dataability對比,所以也放在這個module里。
  • datacenter:數(shù)據(jù)源相關的類AlarmsDataAbility和AlarmRdbStoreMetaDataHelper以及數(shù)據(jù)庫都放在這個module。為了體現(xiàn)數(shù)據(jù)綁定的ui層和數(shù)據(jù)層分離的思想,所以我刻意把數(shù)據(jù)層放在獨立的Module中。
  • mylibrary:放一些工具類

思考一:一個xml布局文件中可以使用多個元數(shù)據(jù)嗎?

先說答案:可以。

核心代碼:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <DirectionalLayout 
  3.     xmlns:ohos="http://schemas.huawei.com/res/ohos" 
  4.     xmlns:metaDataBinding="http://schemas.huawei.com/res/metaDatabinding" 
  5.     ohos:height="match_parent" 
  6.     ohos:width="match_parent" 
  7.     ohos:alignment="center" 
  8.     ohos:orientation="vertical"
  9.  
  10.     <request-meta-data 
  11.         name="data" 
  12.         schema="wang.unclecat.meta-data.hello"/> 
  13.  
  14.     <request-meta-data 
  15.         name="helloUi" 
  16.         class="wang.unclecat.databinding.HelloUiMetaData" 
  17.         schema="wang.unclecat.meta-data.hello.ui"/> 
  18.  
  19.     <Text 
  20.         ohos:id="$+id:text_helloworld" 
  21.         ohos:height="match_content" 
  22.         ohos:width="match_content" 
  23.         ohos:background_element="$graphic:background_ability_main" 
  24.         ohos:layout_alignment="horizontal_center" 
  25.         metaDataBinding:text="@{data.msg}" 
  26.         ohos:text_size="40vp" 
  27.         /> 
  28.  
  29.     <Text 
  30.         ohos:id="$+id:text_helloworld2" 
  31.         ohos:height="match_content" 
  32.         ohos:width="match_content" 
  33.         ohos:background_element="$graphic:background_ability_main" 
  34.         ohos:layout_alignment="horizontal_center" 
  35.         ohos:text_size="40vp" 
  36.         metaDataBinding:text="*{helloUi.toStr(@{helloUi.count})}" 
  37.         /> 
  38.  
  39.  
  40. </DirectionalLayout> 
  1. MetaDataRequestInfo request = new MetaDataRequestInfo.Builder() 
  2.         .fromRequestItems(binding.getRequestMetaData()) 
  3.         .setSyncRequest("data"true
  4.         .setSyncRequest("helloUi"true
  5.         .setCustomDao("data", simpleDao) 
  6.         .setCustomDao("helloUi", simpleDaoUi) 
  7.         .build(); 

demo中,我定義了兩個元數(shù)據(jù)data和helloUi,都可以成功綁定。

實際開發(fā)中,如果一個頁面中有多個業(yè)務上不同的區(qū)域,那么每個區(qū)域綁定的數(shù)據(jù)也必然是不同的。(如果強行定義在一個元數(shù)據(jù)實體中也可以,但是違背了“面向對象”的思想。)

詳見 wang.unclecat.databinding.slice.HelloSlice中示例

思考二:為什么Feature中使用 元數(shù)據(jù)綁定,Json Schema文件必須放在Entry的resource/rawfile.jsonschema路徑下?

否則報錯提示"沒有定義相應的schema"

  1. java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] ohos.mp.metadata.binding.schema.SchemaProto.getFields()' on a null object reference 

 反編譯:

  1. package ohos.mp.metadata.binding.schema
  2.  
  3. public class SchemaParseUtil { 
  4.  
  5.     public static void loadAllMetaDataSchema(Context var0) { 
  6.         try { 
  7.             RawFileEntry var1 = var0.getResourceManager().getRawFileEntry("resources/rawfile/jsonschema/");//這個路徑有問題!??! 
  8.             Entry[] var2 = var1.getEntries(); 
  9.  
  10.             for(int var3 = 0; var3 < var2.length; ++var3) { 
  11.                 String var4 = var2[var3].getPath(); 
  12.                 String var5 = "resources/rawfile/jsonschema/" + var4; 
  13.                 loadSingleMetadataSchema(var0, var5); 
  14.             } 
  15.         } catch (IOException var6) { 
  16.             Log.error("Load All MetaData Schema Failed: IO exception"); 
  17.         } 
  18.     } 

之前我總結過rawfile的使用,有這樣的結論:

就算在myfeature這個module里"resources/..."也是"entry/resources/..."的簡寫形式。

所以,Json Schema文件必須放在Entry中??墒?,這顯然不符合我們的開發(fā)習慣啊,我們應該把相關的資源放在同一個module里。

在本例中,dataability中使用的Json Schemaalarm_schema.json是放在dataability這個module中,我是怎么做到的呢?

其實很簡單

  1. package wang.unclecat.dataability; 
  2.  
  3. @MetaDataApplication(requireData = true, exportData = false
  4. public class MyApplication extends AbilityPackage { 
  5.  
  6.     @Override 
  7.     public void onInitialize() { 
  8.         super.onInitialize(); 
  9.  
  10.         //MetaDataFramework.init(this);//有bug 
  11.         MetaDataFrameworkExtra.init(this);//用它來代替 
  12.     } 

詳見wang.unclecat.mylibrary.MetaDataFrameworkExtra

  1. package wang.unclecat.mylibrary; 
  2.  
  3. public class MetaDataFrameworkExtra { 
  4.  
  5.     public static void init(AbilityPackage var0) { 
  6.         MetaDataFramework.appContext = var0; 
  7.         loadAllMetaDataSchema(var0);//fix: SchemaParseUtil.loadAllMetaDataSchema(var0); 
  8.         UiOperatorManager.init(); 
  9.     } 
  10.  
  11.     //fix: SchemaParseUtil.loadAllMetaDataSchema(var0); 
  12.     public static void loadAllMetaDataSchema(Context var0) { 
  13.         String moduleName = var0.getHapModuleInfo().getModuleName(); 
  14.  
  15.         try { 
  16.             //這里是關鍵!把moduleName加上! 
  17.             RawFileEntry var1 = var0.getResourceManager().getRawFileEntry(moduleName+"/resources/rawfile/jsonschema/"); 
  18.             Entry[] var2 = var1.getEntries(); 
  19.  
  20.             for(int var3 = 0; var3 < var2.length; ++var3) { 
  21.                 String var4 = var2[var3].getPath(); 
  22.                 String var5 = moduleName+"/resources/rawfile/jsonschema/" + var4; 
  23.                 loadSingleMetadataSchema(var0, var5); 
  24.             } 
  25.         } catch (IOException var6) { 
  26.             Log.error("Load All MetaData Schema Failed: IO exception"); 
  27.         } 
  28.  
  29.     } 
  30.  
  31.     //call the method using reflection 
  32.     private static void loadSingleMetadataSchema(Context var0, String var1){ 
  33.         try { 
  34.             Class<?> threadClazz = Class.forName("ohos.mp.metadata.binding.schema.SchemaParseUtil"); 
  35.             Method method = threadClazz.getDeclaredMethod("loadSingleMetadataSchema", Context.class, String.class); 
  36.             method.setAccessible(true); 
  37.             System.out.println(method.invoke(null, var0, var1)); 
  38.         } catch (Exception e) { 
  39.             e.printStackTrace(); 
  40.         } 
  41.     } 

思考三:除了DataAbility作為數(shù)據(jù)源,還可以有其它形式的數(shù)據(jù)源嗎?

codelabs中使用的元數(shù)據(jù)有如下三個:

  1. class ClockRowMetaData extends DataAbilityMetaData 
  2. class CustomMetaData extends DataAbilityMetaData 
  3. class NoteMetaData extends MetaData 

 MetaData是所有元數(shù)據(jù)類的最終基類。

其中ClockRowMetaData和CustomMetaData都繼承自DataAbilityMetaData,而DataAbilityMetaData的基類還是MetaData,DataAbilityMetaData以DataAbility為數(shù)據(jù)源。

NoteMetaData通過自定義的class MyDataHandler implements CustomDao.ICustomMetaDataHandler最終還是使用DataAbility作為數(shù)據(jù)源。

難道我們使用元數(shù)據(jù)綁定框架只能通過DataAbility來訪問數(shù)據(jù)?

當然不是。

com.huawei.middleplatform:ohos-metadata-binding:1.0.0.0中默認有三個MetaData的子類

  1. DataAbilityMetaData 
  2. RdbStoreMetaData 
  3. RemoteServiceMetaData 

 從名字上不難看出,它們本質(zhì)只是數(shù)據(jù)源不同,用法上應該大同小異。

在 喵叔catuncle / TestMetaDataBinding

  • 我也會演示RdbStoreMetaData的用法,它以Rdb(關系型數(shù)據(jù)庫)直接作為數(shù)據(jù)源,而不需要DataAbility中轉。

詳見:wang.unclecat.dataability.alarm.metadata.ClockRowMetaData2

  • 也會直接繼承MetaData自定義我們的HelloUiMetaData元數(shù)據(jù)類,它的數(shù)據(jù)源很簡陋,只是內(nèi)存中的一個變量。

詳見:wang.unclecat.databinding.HelloUiMetaData

  • 至于RemoteServiceMetaData后續(xù)我會慢慢加上,先把這篇文章寫完,不然放得時間太長了。

說了這么多,現(xiàn)在認真回答一下這個問題:除了DataAbility作為數(shù)據(jù)源,可以有Rdb、RemoteService、自定義數(shù)據(jù)源(這里可以根據(jù)自己的需求自由發(fā)揮)

思考四:關于RdbStoreMetaData的問題一:

設置"rdbstore:///wang.unclecat.datacenter.AlarmRdbStoreMetaDataHelper"這樣的uri會報錯

  1. ohos.mp.metadata.binding.databinding.DataSourceConnectionException: 
  2. Make sure [wang.unclecat.datacenter.AlarmRdbStoreMetaDataHelper] is accessible 

 如果把元數(shù)據(jù)數(shù)據(jù)綁定的日志開關打開,我們可以看到這樣的error提示:

  1. "Illegal dataUri. supported type:rdbstore:///wang.unclecat.datacenter.AlarmRdbStoreMetaDataHelper 

 反編譯:

  1. package ohos.mp.metadata.binding.databinding; 
  2.  
  3. public class MetaDataRequestInfo { 
  4.   
  5.     public static class Builder { 
  6.          
  7.         public MetaDataRequestInfo.Builder setRequestSource(String var1, String var2) { 
  8.             if (!this.isIllegalDataUri(var2)) { 
  9.                 String var4 = "|dataability|dataservice|datahandler|"
  10.                 Log.error("Illegal dataUri. supported type: " + var4); 
  11.                 throw new DataSourceNotFoundException("Illegal dataUri. supported type: " + var4); 
  12.             } else { 
  13.                 MetaDataRequestInfo.RequestItem var3 = this.getOrCreateRequest(var1); 
  14.                 var3.dataUri = var2; 
  15.                 return this; 
  16.             } 
  17.         } 
  18.  
  19.         //這個方法有bug?。?! 
  20.         private boolean isIllegalDataUri(String var1) { 
  21.             String var2 = "^(dataability|dataservice|datahandler)\\:\\/.*?\\/.*?\\/.*";//這里有bug?。?!少了rdbstore 
  22.             return Pattern.matches(var2, var1); 
  23.         } 
  24.          
  25.         public MetaDataRequestInfo build() { 
  26.             Iterator var1 = this.requestMap.keySet().iterator(); 
  27.  
  28.             while(var1.hasNext()) { 
  29.                 String var2 = (String)var1.next(); 
  30.                 MetaDataRequestInfo.RequestItem var3 = (MetaDataRequestInfo.RequestItem)this.requestMap.get(var2); 
  31.                 if (var3.predicates != null) { 
  32.                     String var4 = var3.dataUri; 
  33.                     String var5; 
  34.                     if (var4.startsWith("dataability")) { 
  35.                         if (var3.predicates.getType() != Type.DATA_ABILITY_PREDICARES) { 
  36.                             var5 = "MetaDataRequestInfo-build: Invalid predicates type for request " + var3.name + ", should be DataAbilityPredicates object"
  37.                             Log.error(var5); 
  38.                             throw new DataSourceNotFoundException(var5); 
  39.                         } 
  40.                     } else if (var4.startsWith("rdbstore")) { 
  41.                         if (var3.predicates.getType() != Type.RDB_PREDICATES) { 
  42.                             var5 = "MetaDataRequestInfo-build: Invalid predicates type for request " + var3.name + ", should be RdbPredicates object"
  43.                             Log.error(var5); 
  44.                             throw new DataSourceNotFoundException(var5); 
  45.                         } 
  46.                     } else if (!var4.startsWith("dataservice") && var4.startsWith("datahandler") && var3.predicates.getType() != Type.PACMAP_PREDICATES) { 
  47.                         var5 = "MetaDataRequestInfo-build: Invalid predicates type for request " + var3.name + ", should be PacMap object"
  48.                         Log.error(var5); 
  49.                         throw new DataSourceNotFoundException(var5); 
  50.                     } 
  51.                 } 
  52.             } 
  53.  
  54.             return new MetaDataRequestInfo(this); 
  55.         } 
  56.     } 

 發(fā)現(xiàn)boolean isIllegalDataUri(String var1)有bug,解決方法就是跳過這個有bug的驗證方法:

  1. package wang.unclecat.mylibrary; 
  2.  
  3. public class MetaDataFrameworkExtra { 
  4.  
  5.     public static void setRequestSource(MetaDataRequestInfo.Builder builder, String var1, String var2) { 
  6.         MetaDataRequestInfo.RequestItem requestItem = getOrCreateRequest(builder, var1); 
  7.         if (requestItem!=null) { 
  8.             requestItem.dataUri = var2; 
  9.         } 
  10.     } 
  11.  
  12.     //call the method using reflection 
  13.     private static MetaDataRequestInfo.RequestItem getOrCreateRequest(MetaDataRequestInfo.Builder builder, String var1) { 
  14.         try { 
  15.             Class<?> clazz = Class.forName("ohos.mp.metadata.binding.databinding.MetaDataRequestInfo$Builder"); 
  16.             Method method = clazz.getDeclaredMethod("getOrCreateRequest", String.class); 
  17.             method.setAccessible(true); 
  18.             return (MetaDataRequestInfo.RequestItem) method.invoke(builder, var1); 
  19.         } catch (Exception e) { 
  20.             e.printStackTrace(); 
  21.         } 
  22.  
  23.         return null
  24.     } 

思考五:關于RdbStoreMetaData的問題二

在使用RdbStoreMetaData的過程中,我發(fā)現(xiàn)對rdb的操作只有查詢是成功的,插入、刪除、修改都失敗。

反編譯:

  1. package ohos.mp.metadata.binding.dao.inner.rdbstore; 
  2.  
  3. public class RdbStoreDao extends MetaDataDao implements DataObserver { 
  4.     //代碼有省略。。。。 
  5.      
  6.     public void notifyDataAdd(MetaData var1) { 
  7.         //空?所以ui層的改變,不會通過MetaData通知到數(shù)據(jù)層 
  8.     } 
  9.  
  10.     public void notifyDataDelete(MetaData var1) { 
  11.         //空?所以ui層的改變,不會通過MetaData通知到數(shù)據(jù)層 
  12.     } 
  13.  
  14.     public void notifyChange(MetaData var1, String var2, Object var3) { 
  15.         if (var1 instanceof RdbStoreMetaData) { 
  16.             RdbStoreMetaData var4 = (RdbStoreMetaData)var1; 
  17.             RdbStore var5 = this.helper.getRdbStore(); 
  18.             if (var5.isOpen()) { 
  19.                 var5.beginTransaction(); 
  20.                 RdbPredicates var6 = this.createIdentityPredicate(var4); 
  21.  
  22.                 try { 
  23.                     var5.update(var4.createValuesBucketWithoutKeys(this.helper.getMetaDataIdentity()), var6); 
  24.                     var5.markAsCommit(); 
  25.                 } catch (Exception var11) { 
  26.                     Log.error("RdbStore Update Failed: Exception"); 
  27.                 } finally { 
  28.                     var5.endTransaction(); 
  29.                 } 
  30.             } 
  31.         } 
  32.     } 

發(fā)現(xiàn)void notifyDataAdd(MetaData var1)和void notifyDataDelete(MetaData var1)是空實現(xiàn),所以ui上插入、刪除對MetaData的操作不會作用到數(shù)據(jù)層,也許是這個原因吧。當然,也有可能是我的用法不對。

ui上對MetaData的修改操作也同樣不生效,我懷疑RdbStoreDao類中對MetaData沒有調(diào)用addInnerObserver(),這只是和DataAbilityDao的實現(xiàn)對比后的猜測。

思考六:自定義MetaData都有哪幾種方法?

在demo中,目前我只是簡單通過setCustomDao()來設置自定義的SimpleDao并實現(xiàn)SimpleDao.ISimpleMetaDataHandler來完成對數(shù)據(jù)的綁定。

通過了解。自定義MetaData總結一下,有如下兩種方法:

設置SimpleDao并實現(xiàn)相應的SimpleDao.ISimpleMetaDataHandler

設置"datahandler:///com.huawei.metadatabindingdemo.custom_data_source.handler.MyDataHandler"這樣的uri,并實現(xiàn)相應的CustomDao.ICustomMetaDataHandler//codelabs中有演示, 本示例代碼中沒有實現(xiàn)

思考七:抽象類MetaDataDao的作用

此類封裝了對數(shù)據(jù)源的直接操作(連接、增刪改查等)。和常見的數(shù)據(jù)庫orm框架中Dao的概念一致。

默認有五個實現(xiàn)類,前三個和內(nèi)置的MetaData對應,后兩個用于我們自定義MetaData

  1. DataAbilityDao 
  2. RdbStoreDao 
  3. RemoteServiceDao 
  4. SimpleDao 
  5. CustomDao 

順便看一下 MetaDataDaoHelper的反編譯結果:

  1. public class MetaDataDaoHelper { 
  2.     public MetaDataDaoHelper() { 
  3.     } 
  4.  
  5.     public static MetaDataDao createDao(RequestItem var0, IMetaDataObserver var1) { 
  6.         String var2 = var0.dataUri; 
  7.         Object var3 = null
  8.         if (var0.customDao != null) { 
  9.             var3 = var0.customDao; 
  10.         } else if (var2.startsWith("dataability")) { 
  11.             var3 = new DataAbilityDao(); 
  12.         } else if (var2.startsWith("rdbstore")) { 
  13.             var3 = new RdbStoreDao(); 
  14.         } else if (var2.startsWith("dataservice")) { 
  15.             var3 = new RemoteServiceDao(); 
  16.         } else if (var2.startsWith("datahandler")) { 
  17.             var3 = createFromUri(var2); 
  18.         } 
  19.  
  20.         if (var3 == null) { 
  21.             throw new DataSourceNotFoundException("Request name:[" + var0.name + "],Request dataUri:[" + var2 + "]"); 
  22.         } else { 
  23.             ((MetaDataDao)var3).setRequestItem(var0); 
  24.             ((MetaDataDao)var3).setMetaDataObserver(var1); 
  25.             Log.info("createDao: dao = " + var3.getClass().getName()); 
  26.             return (MetaDataDao)var3; 
  27.         } 
  28.     } 
  29.  
  30.     private static MetaDataDao createFromUri(String var0) { 
  31.         String var1 = var0.substring("datahandler:///".length()); 
  32.  
  33.         try { 
  34.             Class var2 = Class.forName(var1); 
  35.             Object var3 = var2.newInstance(); 
  36.             if (var3 instanceof ICustomMetaDataHandler) { 
  37.                 return CustomDao.create((ICustomMetaDataHandler)var3); 
  38.             } else if (var3 instanceof ISimpleMetaDataHandler) { 
  39.                 return SimpleDao.create((ISimpleMetaDataHandler)var3); 
  40.             } else { 
  41.                 throw new DataSourceNotFoundException("Class type of [" + var1 + "] doesn't match:" + ICustomMetaDataHandler.class.getTypeName() + "or" + ISimpleMetaDataHandler.class.getTypeName()); 
  42.             } 
  43.         } catch (ClassNotFoundException var4) { 
  44.             throw new DataSourceNotFoundException("Create custom metadata dao fail missing class in " + var0, var4); 
  45.         } catch (InstantiationException | IllegalAccessException var5) { 
  46.             throw new DataSourceNotFoundException("Instance custom metadata dao fail with for " + var0, var5); 
  47.         } 
  48.     } 

可知MetaDataDao的實例化依賴uri的判斷結果

思考八:跨進程、跨設備訪問dataability類型的uri數(shù)據(jù)源

在同設備安裝 喵叔catuncle / TestDataCenter(配合主程序演示跨進程、跨設備特性),使用體驗上和本地訪問dataability完全一致,本示例代碼中已經(jīng)實現(xiàn)。

理論上講跨設備也應該是一樣的,不過跨設備訪問DataAbility會報如下的錯??墒俏乙呀?jīng)注冊了,并且本地(或本機跨進程)訪問都是好的。

  1. java.lang.IllegalArgumentException: DataAbility register failed, there is no corresponding dataAbility 
  2.  
  3. java.lang.IllegalStateException: No corresponding dataAbility, query failed 

求大神指點跨設備訪問DataAbility的方法!!!

求大神指點跨設備訪問DataAbility的方法!!!

求大神指點跨設備訪問DataAbility的方法!!!

思考九: 如何開啟元數(shù)據(jù)綁定框架的日志

ohos.mp.metadata.binding.common.Log是框架的日志工具類,默認是關閉的,開發(fā)過程中,我們可以打開,方法如下:

  1. try { 
  2.     Field field = ohos.mp.metadata.binding.common.Log.class.getDeclaredField("enableDebug"); 
  3.     field.setAccessible(true); 
  4.     field.set(nulltrue); 
  5. } catch (Exception e) { 
  6.     e.printStackTrace(); 

思考十:ui銷毀之后,綁定關系需要解綁嗎?

答案:需要,框架已自動完成,開發(fā)者無需干預。

還是反編譯:

  1. public abstract class MetaDataBinding implements IMetaDataObserver, LifecycleStateObserver { 
  2.  
  3.     //子類的requestBinding()會調(diào)用此方法 
  4.     protected static <T extends MetaDataBinding> T createBinding(AbilitySlice var0, int layoutId, MetaDataRequestInfo var2, IMetaDataObserver var3) throws DataSourceConnectionException { 
  5.         if (var0 == null) { 
  6.             Log.warn("slice is null when creating binding"); 
  7.             return null
  8.         } else { 
  9.             Lifecycle var4 = var0.getLifecycle(); 
  10.             if (var4 == null) { 
  11.                 Log.warn("lifecycle is null when creating binding"); 
  12.                 return null
  13.             } else { 
  14.                 MetaDataBinding var5 = MetaDataFramework.getMetaDataBinding(layoutId); 
  15.                 var5.createComponent(var0, var4);//inflat布局 
  16.                 var5.requestBind(var2, var3);//綁定數(shù)據(jù) 
  17.                 return var5; 
  18.             } 
  19.         } 
  20.     } 
  21.  
  22.     protected Component createComponent(Context var1, Lifecycle var2) { 
  23.         this.context = var1; 
  24.         Component var3 = LayoutScatter.getInstance(var1).parse(this.getLayoutId(), (ComponentContainer)nullfalse); 
  25.         this.mComponent = new WeakReference(var3); 
  26.         this.lifecycle = var2; 
  27.         this.lifecycle.addObserver(this);//監(jiān)聽生命周期 
  28.         return var3; 
  29.     } 
  30.      
  31.     //響應生命周期變化,自動解綁 
  32.     public void onStateChanged(Event var1, Intent var2) { 
  33.         if (var1 == Event.ON_STOP) { 
  34.             this.unbind();//解綁 
  35.         } 
  36.     } 

 由上可知,框架會監(jiān)聽AbilitySlice的生命周期變化,并在其銷毀時解綁

思考十一:元數(shù)據(jù)綁定的內(nèi)部實現(xiàn)

上面那么多次反編譯,我們也不難看出,元數(shù)據(jù)綁定基于APT(Annotation Processing Tool)即注解處理器。并且框架也由三部分組成(和ButterKinfe這類用到APT技術的框架一樣):

  • ohos-metadata-annotation定義注解
  • ohos-metadata-processor注解處理器
  • ohos-metadata-binding工具類

生成類似如下的文件:

  1. wang.unclecat.dataability.metadatabinding.AlarmrowMetaDataBinding//主要完成數(shù)據(jù)的綁定、數(shù)據(jù)變化的監(jiān)聽 
  2. wang.unclecat.dataability.metadatabinding.Alarm_rowLayoutMapper//完成Ui操作(get和set) 
  3. //對ui的操作,詳細可見package ohos.mp.metadata.binding.uioperate 

思考十二:每個頁面都對應一個DataAbility可以嗎?

我的回答:可以,但是不建議這樣做。

因為DataAbility類似Android的ContentProvider,會跟著應用一起啟動。如果有太多的DataAbility會占用太多內(nèi)存資源。那怎么使用元數(shù)據(jù)綁定的DataAbility呢?

我們看官方文檔是怎么介紹URI的:

詳見:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-data-concept-0000000000043058

元數(shù)據(jù)綁定系列(二):元數(shù)據(jù)綁定進階-鴻蒙HarmonyOS技術社區(qū)
  • query:查詢參數(shù)。
  • fragment:可以用于指示要訪問的子資源。

所以,我們只需要定義一個DataAbility,通過查詢參數(shù)決定要訪問的數(shù)據(jù)資源。

想了解更多內(nèi)容,請訪問:

51CTO和華為官方合作共建的鴻蒙技術社區(qū)

https://harmonyos.51cto.com

 

責任編輯:jianghua 來源: 鴻蒙社區(qū)
相關推薦

2021-09-01 10:37:25

鴻蒙HarmonyOS應用

2021-08-23 10:14:20

鴻蒙HarmonyOS應用

2010-07-30 11:03:54

Flex數(shù)據(jù)綁定

2012-05-29 16:22:02

SpringMVC

2010-07-28 13:11:13

Flex數(shù)據(jù)綁定

2017-08-08 09:15:41

前端JavaScript頁面渲染

2010-07-28 13:31:10

Flex數(shù)據(jù)綁定

2016-10-27 13:40:02

編程語言 數(shù)據(jù)庫

2010-08-05 15:06:19

Flex數(shù)據(jù)綁定

2021-02-11 08:27:28

數(shù)據(jù)

2010-12-20 15:13:11

Windows For

2010-07-30 10:45:08

Flex數(shù)據(jù)綁定

2009-12-24 11:15:59

WPF數(shù)據(jù)綁定

2010-08-12 11:34:15

Flex數(shù)據(jù)綁定

2023-10-07 11:04:58

WPF數(shù)據(jù)UI

2010-07-30 09:08:21

Flex數(shù)據(jù)綁定

2009-08-10 16:47:45

Visual C#數(shù)據(jù)

2023-02-27 15:46:19

數(shù)據(jù)元元數(shù)據(jù)

2021-02-19 23:07:02

Vue綁定組件

2010-08-10 10:56:39

點贊
收藏

51CTO技術棧公眾號