JetpackのViewModelとLiveData
この章で達成されるレンダリング
ViewModelの利点
1.ページ構成の変更とデータは失われません。
構成の変更(水平および垂直画面回転、ソフトキーボードモード、デバイス解像度、およびアクセス許可スイッチ)によってデバイスが再構築されると、アクティビティ/フラグメントが再構築され、その結果、ViewModelのデータが失われることはありません(データの保存と読み取り以下で説明します)、LiveDataを使用すると、ページを再構築してページを再レンダリングした後、すぐに最新の保存データを受け取ることができます。
2.ライフサイクルセンシング
一部のネットワーク要求またはデータ処理がViewModelで実行されることは避けられません。onCleared()メソッドを上書きして、一部のクリーンアップ操作を終了し、メモリを解放することができます。このメソッドは、ホストがonDestroyのときに呼び出されます。
3.データ共有
単一のアクティビティ、複数のフラグメントページの場合、ViewModelを使用してページ間のデータ共有を実現できます
ジェットパックにViewModelをインポートする
def lifecycle_version = "2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
ViewModelケース
1.まず、ViewModelを継承する独自のmyViewModelを作成します
ここでは、変数numerを格納するために使用されます
import androidx.lifecycle.ViewModel;
public class MyViewModel extends ViewModel {
public int number =0;
}
2. myviewmodleオブジェクトをインスタンス化するには、ViewModelProviders依存関係を手動でインポートする必要があることに注意する必要があります。
//创建MyViewModel
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
3.ボタンをクリックして、myviewmodelの値を操作します
public class MainActivity extends AppCompatActivity {
MyViewModel myViewModel;
TextView textView;
Button button1,button2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init_view();
//创建MyViewModel
myViewModel = ViewModelProviders.of(this).get(MyViewModel.class);
textView.setText(String.valueOf(myViewModel.number));
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.number++;
textView.setText(String.valueOf(myViewModel.number));
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
myViewModel.number+=2;
textView.setText(String.valueOf(myViewModel.number));
}
});
}
private void init_view() {
textView=findViewById(R.id.textView);
button1=findViewById(R.id.add);
button2=findViewById(R.id.button2);
}
}
この例では、ViewModelを使用しています。これにより、画面が上下逆になったときにデータが失われることはありません。
LiveDataの概要
公式説明
LiveDataは、監視およびデータを保持できるクラスです。他の通常の監視対象とは異なり、コンポーネントのライフサイクルを考慮します。つまり、アクティビティ、フラグメント、およびサービスのライフサイクルを尊重し、 Start and Resume(ライフアクティビティサイクル)のコンポーネントのオブザーバーを更新します。
LiveDataを使用する利点:
1.uiがデータと同期していることを確認します。LiveDataはオブザーバーパターンに従います。LiveDataはコンポーネントのライフサイクルが変更されたときに通知します。コードをマージしてこれらのオブザーバーオブジェクトのUIを更新できます。ライフサイクル管理により、オブザーバーのUIを自信を持って更新できます。 。
2.メモリリークはありません。オブザーバーはライフサイクルにバインドされているため、ライフサイクルが破棄されると、オブザーバーは自動的にクリーンアップされます。
3.アクティビティを停止しても、クラッシュは発生しません。スタック内のアクティビティなど、オブザーバーが配置されているコンポーネントのライフサイクルがアクティブでない場合、オブザーバーはこの時点でデータを受信しません。
4.ライフサイクルを手動で管理する必要はありません。uiコンポーネントは関連データのみを監視し、監視を終了または開始する必要はありません。LiveDataは、監視中にライフサイクルの変化を認識しているため、これらを自動的に管理します。
5.常に最新のデータ。アクティビティがバックグラウンドから戻ると、すぐに最新のデータを受け取ります。
6.適切な構成変更。画面の回転などの構成変更によりアクティビティまたはフラグメントが再構築された場合、最新のデータをすぐに受信します。
7.リソースを共有します。LiveDataオブジェクトを継承し、シングルトンパターンを使用してシステムサービスにラップし、アプリで共有できるようにすることができます。このLiveDataオブジェクトは、システムサービスに接続されると、リソースを必要とするすべてのオブザーバーがオブジェクトを監視できます。
LiveDataを使用する理由
以前、ViewModelのみを使用する場合、データが変更されるたびtextView.setText(String.valueOf(myViewModel.number));
に再割り当てを呼び出す必要があることを確認しました。このステップを保存する方法はありますか?次に、LiveDataが役立ちます。
1.まず、ViewModelを作成します。データのタイプが変更されたことは注目に値します。次に、それを使用しMutableLiveData<Integer> Number
て、コンストラクターで番号を割り当てます。
LiveDataケース
public class LiveData extends ViewModel {
private MutableLiveData<Integer> Number;
public MutableLiveData<Integer> getNumber() {
if(Number == null){
Number = new MutableLiveData<>();
Number.setValue(0);
}
return Number;
}
//该函数用于对数据进行操作,比如+1,或者-1
public void addNumber(int n){
Number.setValue(Number.getValue()+n);
}
}
2.オブザーバーモードを使用して、データの変更を監視します。liveData.getNumber().observe(this, new Observer<Integer>() {
public class LiveDataActivity extends AppCompatActivity {
ImageView button1,button2;
TextView textView;
LiveData liveData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_live_data);
init_view();
//获取ViewModel对象
liveData = ViewModelProviders.of(this).get(LiveData.class);
//添加观察者,监听数据的改变,并在数据改变的时候重新赋值
liveData.getNumber().observe(this, new Observer<Integer>() {
@Override
//当数据改变就呼救此函数
public void onChanged(Integer integer) {
//显示当前的数
textView.setText(String.valueOf(integer));
}
});
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//加1操作
liveData.addNumber(1);
}
});
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//减1操作
liveData.addNumber(-1);
}
});
}
private void init_view() {
textView=findViewById(R.id.textView2);
button1=findViewById(R.id.imageView);
button2=findViewById(R.id.imageView2);
}
}