JetPack組件 ViewModel+LiveData

一直以來蛔翅,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. 作用

  1. 用以解決的痛點
  • 瞬態(tài)數(shù)據(jù)丟失
  • 異步調(diào)用內(nèi)存泄漏
  • 類膨脹提高維護(hù)難度和測試難度
  1. 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.
        });
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末珠十,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子凭豪,更是在濱河造成了極大的恐慌焙蹭,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嫂伞,死亡現(xiàn)場離奇詭異孔厉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)帖努,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門撰豺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人然磷,你說我怎么就攤上這事郑趁。” “怎么了姿搜?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵寡润,是天一觀的道長。 經(jīng)常有香客問我舅柜,道長梭纹,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任致份,我火速辦了婚禮变抽,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘氮块。我一直安慰自己绍载,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布滔蝉。 她就那樣靜靜地躺著击儡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蝠引。 梳的紋絲不亂的頭發(fā)上阳谍,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天蛀柴,我揣著相機(jī)與錄音,去河邊找鬼矫夯。 笑死鸽疾,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的训貌。 我是一名探鬼主播制肮,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼旺订!你這毒婦竟也來了弄企?” 一聲冷哼從身側(cè)響起超燃,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤区拳,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后意乓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體樱调,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年届良,在試婚紗的時候發(fā)現(xiàn)自己被綠了笆凌。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡士葫,死狀恐怖乞而,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慢显,我是刑警寧澤爪模,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站荚藻,受9級特大地震影響屋灌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜应狱,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一共郭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疾呻,春花似錦除嘹、人聲如沸谱醇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弛说。三九已至氧枣,卻和暖如春十籍,著一層夾襖步出監(jiān)牢的瞬間箱硕,已是汗流浹背期揪。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留晦款,地道東北人炎功。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像缓溅,于是被迫代替她去往敵國和親蛇损。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容