jetpack
Jetpack 是一套庫、工具和指南,可幫助開發(fā)者更輕松地編寫優(yōu)質(zhì)應(yīng)用。這些組件可幫助您遵循最佳做法、讓您擺脫編寫樣板代碼的工作并簡化復(fù)雜任務(wù),以便您將精力集中放在所需的代碼上。
Jetpack 包含與平臺(tái) API 解除捆綁的?androidx.*?軟件包庫。這意味著,它可以提供向后兼容性,且比 Android 平臺(tái)的更新頻率更高,以此確保您始終可以獲取最新且最好的 Jetpack 組件版本。
這里是jetpack官方文檔jetpack文檔傳送門
viewModel
ViewModel?類旨在以注重生命周期的方式存儲(chǔ)和管理界面相關(guān)的數(shù)據(jù)。ViewModel?類讓數(shù)據(jù)可在發(fā)生屏幕旋轉(zhuǎn)等配置更改后繼續(xù)存在。
Android 框架可以管理界面控制器(如 Activity 和 Fragment)的生命周期。Android 框架可能會(huì)決定銷毀或重新創(chuàng)建界面控制器,以響應(yīng)完全不受您控制的某些用戶操作或設(shè)備事件。
如果系統(tǒng)銷毀或重新創(chuàng)建界面控制器,則存儲(chǔ)在其中的任何臨時(shí)性界面相關(guān)數(shù)據(jù)都會(huì)丟失。例如,應(yīng)用的某個(gè) Activity 中可能包含用戶列表。因配置更改而重新創(chuàng)建 Activity 后,新 Activity 必須重新提取用戶列表。對(duì)于簡單的數(shù)據(jù),Activity 可以使用?onSaveInstanceState()?方法從?onCreate()?中的捆綁包恢復(fù)其數(shù)據(jù),但此方法僅適合可以序列化再反序列化的少量數(shù)據(jù),而不適合數(shù)量可能較大的數(shù)據(jù),如用戶列表或位圖。
另一個(gè)問題是,界面控制器經(jīng)常需要進(jìn)行異步調(diào)用,這些調(diào)用可能需要一些時(shí)間才能返回結(jié)果。界面控制器需要管理這些調(diào)用,并確保系統(tǒng)在其銷毀后清理這些調(diào)用以避免潛在的內(nèi)存泄露。此項(xiàng)管理需要大量的維護(hù)工作,并且在因配置更改而重新創(chuàng)建對(duì)象的情況下,會(huì)造成資源的浪費(fèi),因?yàn)閷?duì)象可能需要重新發(fā)出已經(jīng)發(fā)出過的調(diào)用。
諸如 Activity 和 Fragment 之類的界面控制器主要用于顯示界面數(shù)據(jù)、對(duì)用戶操作做出響應(yīng)或處理操作系統(tǒng)通信(如權(quán)限請(qǐng)求)。如果要求界面控制器也負(fù)責(zé)從數(shù)據(jù)庫或網(wǎng)絡(luò)加載數(shù)據(jù),那么會(huì)使類越發(fā)膨脹。為界面控制器分配過多的責(zé)任可能會(huì)導(dǎo)致單個(gè)類嘗試自己處理應(yīng)用的所有工作,而不是將工作委托給其他類。以這種方式為界面控制器分配過多的責(zé)任也會(huì)大大增加測(cè)試的難度。
從界面控制器邏輯中分離出視圖數(shù)據(jù)所有權(quán)的做法更易行且更高效。
1:首先呢我們先添加我們的viewModel的依賴?
這個(gè)我們也可以直接到官方網(wǎng)站去查找傳送門
?dependencies {def lifecycle_version = "2.2.0"
// ViewModel
implementation
"androidx.lifecycle:lifecycle-viewmodel:$lifecycle_version"http:// LiveData
implementation
"androidx.lifecycle:lifecycle-livedata:$lifecycle_version"http:// Lifecycles only (without ViewModel or LiveData)
implementation
"androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation
"androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor
"androidx.lifecycle:lifecycle-compiler:$lifecycle_version"http:// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation
"androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation
"androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation
"androidx.arch.core:core-testing:$lifecycle_version"}
2:添加完庫之后我們創(chuàng)建一個(gè)顯示界面,
我這里添加了兩個(gè)button和兩個(gè)textview用于點(diǎn)擊計(jì)數(shù)和顯示。
布局很簡單:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
? ? xmlns:app="http://schemas.android.com/apk/res-auto"
? ? xmlns:tools="http://schemas.android.com/tools"
? ? android:layout_width="match_parent"
? ? android:layout_height="match_parent"
? ? tools:context=".MainActivity">
? ? ? ? android:id="@+id/guideline"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:orientation="vertical"
? ? ? ? app:layout_constraintGuide_begin="205dp" />
? ? ? ? android:id="@+id/btn1"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="Button1"
? ? ? ? app:layout_constraintBottom_toBottomOf="parent"
? ? ? ? app:layout_constraintEnd_toStartOf="@+id/guideline"
? ? ? ? app:layout_constraintStart_toStartOf="parent"
? ? ? ? app:layout_constraintTop_toTopOf="parent" />
? ? ? ? android:id="@+id/btn2"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="Button2"
? ? ? ? app:layout_constraintBottom_toBottomOf="parent"
? ? ? ? app:layout_constraintEnd_toEndOf="parent"
? ? ? ? app:layout_constraintStart_toStartOf="@+id/guideline"
? ? ? ? app:layout_constraintTop_toTopOf="parent" />
? ? ? ? android:id="@+id/tv1"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="TextView"
? ? ? ? app:layout_constraintBottom_toTopOf="@+id/btn1"
? ? ? ? app:layout_constraintEnd_toStartOf="@+id/guideline"
? ? ? ? app:layout_constraintStart_toStartOf="parent"
? ? ? ? app:layout_constraintTop_toTopOf="parent" />
? ? ? ? android:id="@+id/tv2"
? ? ? ? android:layout_width="wrap_content"
? ? ? ? android:layout_height="wrap_content"
? ? ? ? android:text="TextView"
? ? ? ? app:layout_constraintBottom_toTopOf="@+id/btn2"
? ? ? ? app:layout_constraintEnd_toEndOf="parent"
? ? ? ? app:layout_constraintStart_toStartOf="@+id/guideline"
? ? ? ? app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
下面就是創(chuàng)建一個(gè)viewModel類了。
public class ConstomViewModel extends ViewModel {
private int tickadd1=0;
? ? private int tickadd2=0;
? ? public int getTickadd1() {
return tickadd1;
? ? }
public void setTickadd1(int tickadd1) {
this.tickadd1 =tickadd1;
? ? }
public int getTickadd2() {
return tickadd2;
? ? }
public void setTickadd2(int tickadd2) {
this.tickadd2 =tickadd2;
? ? }
}
3:創(chuàng)建activity
public class ConstomViewModelActivity extends AppCompatActivity {
private? ConstomViewModel constomViewModel;
? ? private TextView? tv1,tv2;
? ? private Button btn1,btn2;
? ? @Override
? ? protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
? ? ? ? setContentView(R.layout.activity_constom_view_model);
? ? ? ? constomViewModel=new ViewModelProvider(this).get(ConstomViewModel.class);
? ? ? ? tv1=findViewById(R.id.tv1);
? ? ? ? tv2=findViewById(R.id.tv2);
? ? ? ? btn1=findViewById(R.id.btn1);
? ? ? ? btn2=findViewById(R.id.btn2);
? ? ? ? tv1.setText(String.valueOf(constomViewModel.getTickadd1()));
? ? ? ? tv2.setText(String.valueOf(constomViewModel.getTickadd2()));
? ? ? ? btn1.setOnClickListener(new View.OnClickListener() {
@Override
? ? ? ? ? ? public void onClick(View v) {
constomViewModel.setTickadd1(constomViewModel.getTickadd1()+1);
? ? ? ? ? ? ? ? tv1.setText(String.valueOf(constomViewModel.getTickadd1()));
? ? ? ? ? ? }
});
? ? ? ? btn2.setOnClickListener(new View.OnClickListener() {
@Override
? ? ? ? ? ? public void onClick(View v) {
constomViewModel.setTickadd2(constomViewModel.getTickadd2()+1);
? ? ? ? ? ? ? ? tv2.setText(String.valueOf(constomViewModel.getTickadd2()));
? ? ? ? ? ? }
});
? ? }
}
下面是運(yùn)行效果
其優(yōu)點(diǎn)是在上面都有介紹了這里就不在多說了,這就是一個(gè)簡單的viewmodel使用的例子: