JetPack組件 ViewModel+LiveData

一直以來,Android開發(fā)都充斥了大量的不規(guī)范的操作和重復代碼,比如生命周期的管理,開發(fā)過程的重復,項目架構的選擇等等。谷歌IO大會上,Google官方向推出了 Jetpack,旨在讓開發(fā)者們能夠更好,更快,更規(guī)范地開發(fā)出優(yōu)質應用。

  • lifecycle
  • DataBinding
  • Navigation
  • Room
  • WorkManger
  • Paging

1. 作用

  1. 用以解決的痛點
  • 瞬態(tài)數(shù)據(jù)丟失
  • 異步調用內(nèi)存泄漏
  • 類膨脹提高維護難度和測試難度
  1. viewModel是什么?
  • 它是介于View(視圖)和Model(數(shù)據(jù)模型)之間的橋梁
  • 使視圖和數(shù)據(jù)能夠分離,也能保持通信

官方解釋:ViewModel類是被設計用來以可感知生命周期的方式存儲和管理 UI 相關數(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 簡單應用
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);

       //構建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));
           }
       });
   }
}

編譯后,以上在屏幕旋轉之后數(shù)據(jù)任然存在不會丟失,是應為ViewModel的特性可以讓它獨立于配置變化。
注意:

  • 不要向ViewModel 中傳入Context,會導致內(nèi)存泄漏。
  • 如果必須使用Context,使用AndoridViewModel中的Application。
3. 使用ViewModel + LiveData 在 ViewModel中數(shù)據(jù)變化時通知頁面

LiveData的優(yōu)勢

  • 確保界面符合數(shù)據(jù)狀態(tài)
  • 不會反生內(nèi)存泄漏
  • 不會因Activity 停止而導致崩潰
  • 不再需要手動處理生命周期
  • 數(shù)據(jù)始終保持最新狀態(tài)
  • 適當?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);

        //構建ViewModel實例
        viewModel = new ViewModelProviders(this,new ViewModelProvider
        .AndroidViewModelFactory(getApplication())).get(MyViewModel.class);

        mTextView.setText(String.valueOf(viewModel.getCurrentSecond().getValue()));
     
        //  viewModel 中的數(shù)據(jù)變化會動態(tài)回調 
        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.
        });
    }
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容