data-mediator
see English document by click this.
- 一個數(shù)據(jù)層的框架晾虑。利用編譯時注解技術(shù)灸叼, 在java和android平臺自動生成 數(shù)據(jù)實體及相關(guān)的代碼。
方便數(shù)據(jù)層的使用。支持gson. 通過操作binder和代理 實現(xiàn)絕大部分開發(fā)屬性設置拇砰。(setText, setTextColor 等等)
支持數(shù)據(jù)統(tǒng)計(即將上線)
導航
問題及目標
- 現(xiàn)有問題:
通常況下我們寫app: 需要寫很多實體,常用的就是和server交互的實體.
在版本不斷迭代的情況下,數(shù)據(jù)模型可能會很很多次(CRUD 字段甚至直接刪除整個module).
即使我們使用parcelable 代碼生成器,也經(jīng)常要ALT+insert去重新生成脱篙。toString那些更不用說了。
而且如果用gson注解映射悦施, 就更不太方便了并扇。
如果想鏈式編程....也不方便。
... - 基于此抡诞,我設計了這個數(shù)據(jù)中介者框架穷蛹。
- 它的目標:
由于數(shù)據(jù)層是直接和業(yè)務打交道。很可能經(jīng)常變動昼汗。為了減小這種變動肴熏。我想出了數(shù)據(jù)中介者框架(data-mediator).
當然它還會支持很多特性. 未來還會完成更加復雜業(yè)務任務.
設計思想
整個設計分3層: 模型層,代理層顷窒,調(diào)用層
模型層:代表的是數(shù)據(jù)模型接口and實現(xiàn)
代理層:數(shù)據(jù)實體的代理
調(diào)用層:操作模型和代理的
特點
自動生成數(shù)據(jù)的接口和實現(xiàn)類.可自動實現(xiàn)Serializable和 Parcelable(android)接口蛙吏。
自動生成get/is , set , toString方法.
自動生成代理層 以便監(jiān)聽數(shù)據(jù)變化。-
字段:
- 1, 支持多種類型 , 8大基本類型(int,long,short,byte,float,double,boolean ,char)及其包裝類型鞋吉, String類型,
和其他類型 .數(shù)組和list結(jié)構(gòu)同樣支持鸦做。(map暫不支持parcelable) - 2, 支持生成字段的gson注解 for 'Google-Gson'.
- 3, 支持多域, 比如: 重置(IResetable接口), 拷貝(ICopyable接口), 共享(Shareable), 快照(ISnapable)接口谓着。toString.
作用: 比如重置: 很多時候我們調(diào)用了數(shù)據(jù)的一些方法泼诱,改變了一些屬性。然后想重置以便重新使用赊锚。
比如 toString. 可選擇某些字段參加或者不參加toString方法. hashCode和equals同理
- 1, 支持多種類型 , 8大基本類型(int,long,short,byte,float,double,boolean ,char)及其包裝類型鞋吉, String類型,
支持List/SparseArray屬性編輯器治筒。 (相當于對list/SparseArray的增刪改增加了便捷操作 和回調(diào))
-
支持依賴或繼承 @Field注解的接口(代表數(shù)據(jù)實體). 繼承只能繼承一個。
- 平常我們寫 BaseEntity(內(nèi)有代表http/https響應的code, message, data字段), 通常業(yè)務接口的數(shù)據(jù)會繼承這個BaseEntity舷蒲。
所以這里規(guī)定 繼承@Field注解的接口(代表數(shù)據(jù)實體) 只能一個矢炼。否則error.
- 平常我們寫 BaseEntity(內(nèi)有代表http/https響應的code, message, data字段), 通常業(yè)務接口的數(shù)據(jù)會繼承這個BaseEntity舷蒲。
支持鏈式調(diào)用. data-mediator-compiler 1.0.9 之后默認鏈式。
1), 如果需要回到普通的java bean. 則需要將注解 @fields的方法 boolean enableChain()阿纤。 返回false.
2), 需要注意的是句灌,如果模型之間有繼承關(guān)系。則需要將父module定義的enableChain 和 child的 enableChain 值相同, 否則編譯錯誤。
3), 下面是示例:
DataMediator<StudentModule> mediator = DataMediatorFactory.createDataMediator(StudentModule.class);
//數(shù)據(jù)代理層
mediator.getDataProxy()
.setName(null)
.setAge(0)
.setId(0);
//數(shù)據(jù)真正的模型實現(xiàn)
mediator.getData().setName(null)
.setAge(0)
.setId(0);
- 支持數(shù)據(jù)緩存 (使用請參考下面進階指南)
- 支持android平臺的雙向綁定, 新增萬能的Binder. 支持綁定任意控件的屬性胰锌。(常用的已經(jīng)集成)
綁定以后操作數(shù)據(jù)代理就是操作view. (使用請參考下面進階指南)
快速入門
1, 在項目根目錄添加apt依賴骗绕。
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
2, 在使用的app module中加入。apt plugin
apply plugin: 'com.neenbedankt.android-apt'
3, 添加dependencies
dependencies {
//......
compile 'com.heaven7.java.data.mediator:data-mediator:<see release>'
compile 'com.heaven7.java.data.mediator.annotation:data-mediator-annotations:<see release>'
apt 'com.heaven7.java.data.mediator.compiler:data-mediator-compiler:<see release>'
apt 'com.squareup:javapoet:1.9.0'
// 如果需要生成對應的gson注解资昧。請加入gson依賴酬土。比如
compile "com.google.code.gson:gson:2.7"
// 如果要支持android平臺的數(shù)據(jù)綁定. 請?zhí)砑右蕾? compile 'com.heaven7.android.data.mediator:data-mediator-android:<see release>'
}
4, 開始定義你的數(shù)據(jù)實體。比如我要定義關(guān)于學生的數(shù)據(jù)模型, 需要實現(xiàn)Serializable, Parcelable.
假如學生有格带。年齡撤缴,名稱, id屬性。
那么簡單的數(shù)據(jù)定義為:
@Fields({
@Field(propName = "age" , type = int.class, flags = FLAGS_ALL_SCOPES),
@Field(propName = "name" , type = String.class, flags = FLAGS_ALL_SCOPES),
@Field(propName = "id" , type = long.class, flags = FLAGS_ALL_SCOPES),
})
public interface Student extends Serializable, Parcelable{
}
5, 點擊android studio 工具欄上的圖標
即可自動生成代碼(數(shù)據(jù)定義沒變化叽唱,不會重新生成)屈呕。
會自動生成 xxxModule 模型接口, xxxxModule_Impl 模型實現(xiàn) 。
6, 調(diào)用示例 (來自data-mediator-demo下的TestPropertyChangeActivity)
/**
* 屬性改變demo
* Created by heaven7 on 2017/9/18 0018.
*/
public class TestPropertyChangeActivity extends BaseActivity {
@BindView(R.id.tv_desc)
TextView mTv_desc;
@BindView(R.id.bt_set_text_on_TextView)
Button mBt_changeProperty;
@BindView(R.id.bt_set_text_on_mediator)
Button mBt_temp;
DataMediator<StudentModule> mMediator;
@Override
protected int getLayoutId() {
return R.layout.ac_test_double_bind;
}
@Override
protected void onInit(Context context, Bundle savedInstanceState) {
mBt_changeProperty.setText("click this to change property");
mBt_temp.setVisibility(View.GONE);
//為數(shù)據(jù)模型創(chuàng)建 中介者棺亭。
mMediator = DataMediatorFactory.createDataMediator(StudentModule.class);
//添加屬性callback
mMediator.addDataMediatorCallback(new DataMediatorCallback<StudentModule>() {
@Override
public void onPropertyValueChanged(StudentModule data, Property prop, Object oldValue, Object newValue) {
Logger.w("TestPropertyChangeActivity","onPropertyValueChanged","prop = "
+ prop.getName() + " ,oldValue = " + oldValue + " ,newValue = " + newValue);
mTv_desc.setText(String.valueOf(newValue));
}
});
mMediator.getDataProxy().setName("heaven7");
}
@OnClick(R.id.bt_set_text_on_TextView)
public void onClickSetTextOnTextView(View v){
mMediator.getDataProxy().setName("time: " + System.currentTimeMillis());
}
}
進階指南
混淆配置
-keepclasseswithmembers public class * implements com.heaven7.java.data.mediator.DataPools$Poolable{
*;
}
-keepclasseswithmembers public interface * extends com.heaven7.java.data.mediator.DataPools$Poolable{
*;
}
-keep class * extends com.heaven7.java.data.mediator.BaseMediator{
*;
}
-keep class com.heaven7.java.data.mediator.BaseMediator
-keep public class com.heaven7.android.data.mediator.BinderSupplierImpl
# 1.1.3 新增
-keep public class com.heaven7.android.data.mediator.DataMediatorDelegateImpl
github 項目地址:github.com/LightSun/da…
歡迎大家star. 提issue 或者contribute .
Thanks for read !!!
ps: 如果技術(shù)上或者框架有任何問題虎眨。我都會快速解決的。
author:heaven7