一直以來蛔翅,Android開發(fā)都充斥了大量的不規(guī)范的操作和重復(fù)代碼瓶殃,比如生命周期的管理概荷,開發(fā)過程的重復(fù),項目架構(gòu)的選擇等等碌燕。谷歌IO大會上误证,Google官方向推出了 Jetpack,旨在讓開發(fā)者們能夠更好修壕,更快愈捅,更規(guī)范地開發(fā)出優(yōu)質(zhì)應(yīng)用。
lifecycle
- DataBinding
- Navigation
- Room
- WorkManger
- Paging
1. 作用
- 用以解決的痛點
- 瞬態(tài)數(shù)據(jù)丟失
- 異步調(diào)用內(nèi)存泄漏
- 類膨脹提高維護(hù)難度和測試難度
- viewModel是什么?
- 它是介于View(視圖)和Model(數(shù)據(jù)模型)之間的橋梁
- 使視圖和數(shù)據(jù)能夠分離慈鸠,也能保持通信
官方解釋:ViewModel類是被設(shè)計用來以可感知生命周期的方式存儲和管理 UI 相關(guān)數(shù)據(jù)蓝谨,ViewModel中數(shù)據(jù)會一直存活即使 activity configuration發(fā)生變化,比如橫豎屏切換的時候。
2. 使用
1.gradle依賴
//引入AndroidX吧,替換掉support包
implementation 'androidx.appcompat:appcompat:1.0.2'
def lifecycle_version = "2.0.0"
// ViewModel and LiveData
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
2. ViewModel 簡單應(yīng)用
public class MyViewModel extends ViewModel {
public int number;
}
public class MainActivity extends FragmentActivity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.tv_content);
//構(gòu)建ViewModel實例
MyViewModel viewModel = new ViewModelProviders(this,new ViewModelProvider
.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
mTextView.setText(String.valueOf(viewModel.number))
findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//點擊按鈕 更新number數(shù)據(jù)
mTextView.setText(String.valueOf(++viewModel.number));
}
});
}
}
編譯后譬巫,以上在屏幕旋轉(zhuǎn)之后數(shù)據(jù)任然存在不會丟失咖楣,是應(yīng)為ViewModel的特性可以讓它獨立于配置變化。
注意:
- 不要向ViewModel 中傳入Context芦昔,會導(dǎo)致內(nèi)存泄漏诱贿。
- 如果必須使用Context,使用AndoridViewModel中的Application。
3. 使用ViewModel + LiveData 在 ViewModel中數(shù)據(jù)變化時通知頁面
LiveData的優(yōu)勢
- 確保界面符合數(shù)據(jù)狀態(tài)
- 不會反生內(nèi)存泄漏
- 不會因Activity 停止而導(dǎo)致崩潰
- 不再需要手動處理生命周期
- 數(shù)據(jù)始終保持最新狀態(tài)
- 適當(dāng)?shù)呐渲酶?/li>
- 共享資源
public class MyViewModel extends ViewModel {
public final MutableLiveData<Integer> currentSecond = new MutableLiveData<>();
public MutableLiveData<Integer> getCurrentSecond(){
if(currentSecond==null){
currentSecond = new MutableLiveData<>();
currentSecond.setValue(0);
}
returen currentSecond;
}
}
public class MainActivity extends FragmentActivity {
private TextView mTextView;
private MyViewModel viewModel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextView = findViewById(R.id.tv_content);
//構(gòu)建ViewModel實例
viewModel = new ViewModelProviders(this,new ViewModelProvider
.AndroidViewModelFactory(getApplication())).get(MyViewModel.class);
mTextView.setText(String.valueOf(viewModel.getCurrentSecond().getValue()));
// viewModel 中的數(shù)據(jù)變化會動態(tài)回調(diào)
viewModel.getCurrentSecond().observe(this,new Observer<Integer>(){
@Override
public void onChange(Integer data){
mTextView.setText(String.valueOf(data));
}
});
startTime();
}
private void startTime(){
new Timer().schedule(new TimerTask(){
@Override
public void run(){
Integer value = viewModel.getCurrentSecond().getValue();
// 非UI線程 postValue咕缎、UI線程 setValue
viewModel.getCurrentSecond().postValue(value+1);
}
},1000,1000);
}
}
4. 使用ViewModel + LiveData 實現(xiàn)Fragment間通信
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 實現(xiàn)通信的重點是 使用 getActivity()
model = new ViewModelProviders(getActivity(),new ViewModelProvider
.AndroidViewModelFactory(getApplication())).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 實現(xiàn)通信的重點是 使用 getActivity()
SharedViewModel model = new ViewModelProviders(getActivity(),new ViewModelProvider
.AndroidViewModelFactory(getApplication())).get(SharedViewModel.class);
model.getSelected().observe(this, { item ->
// Update the UI.
});
}
}