Android JetPack系列之——ViewModel

android開發(fā)的架構經歷了MVC、MVP脸侥、MVVM建邓,三種架構方式沒有好與差的區(qū)分,在實際的開發(fā)過程中因人而異湿痢,因項目而異涝缝。但是扑庞,最近幾年,隨著Google不斷對android的體系進行梳理拒逮,加之不斷推出的API罐氨。MVVM的模式越來越受到開發(fā)者的喜愛,而在MVVM的架構中滩援,很重要的一個組件就是我們今天的主角——ViewModel栅隐。

ViewModel的簡介

在頁面(Activity/Fragment)功能較為簡單的情況下,我們通常會將UI交互玩徊、與數據獲取等相關的業(yè)務邏輯全部寫在頁面中租悄。但是在頁面功能復雜的情況下,代碼量會變的非常多恩袱,后期的維護和擴展非常的麻煩泣棋,這是典型的MVC的架構模式。其實真正的在理想情況下畔塔,應該是UI展示與數據處理分開潭辈,即各司其職。頁面(Activity/Fragment)只負責UI的展示澈吨,數據的處理由專門的類去實現把敢,而這個就是我們ViewModel的由來。

ViewModel可以這么理解: 它是介于View(視圖)和Model(數據模型)之間的一個東西谅辣。它起到了橋梁的作用修赞,使視圖和數據既能分離,也能保持通信桑阶。即ViewModel 是以生命周期的方式存儲與管理UI相關數據柏副。

ViewModel的作用

  • 在MVVM模式中,使Model與View分離
  • 存儲數據
  • 負責為UI準備數據

ViewModel的生命周期

這里有一張官網關于ViewModel的生命周期的圖


viewmodel.png

從這張圖中联逻,我們不難看出:

(1)ViewModel的生命周期比Activity或者Fragment長搓扯,因此 ViewModel不能持有Context的對象,不然會出現內存泄漏包归。
(2)Activity在生命周期中可能會觸發(fā)多次onCreate(),而ViewModel則只會在第一次onCreate()時創(chuàng)建铅歼,然后直到最后Activity銷毀公壤。

ViewModel的基本使用

1.添加依賴

implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'

2.新建類繼承自ViewModel類

class UserModel : ViewModel() {

    val userLiveData = MutableLiveData<User>()

    init {
        userLiveData.postValue(User(1, "jack"))
    }

    fun doSomething() {
        val user = userLiveData.value?.apply {
            age = (100..500).random()
            name = "jack$age"
        }
        userLiveData.value = user
    }
}

3.在Activity/Fragment中將ViewModel進行關聯

// Activity中的使用
class ViewModuleActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_view_module)
        // 獲取ViewModel實例
        val userModel = ViewModelProvider(this).get(UserModel::class.java)
        // 利用livedata實現雙向綁定
        userModel.userLiveData.observe(this,
            Observer<User> { t -> username.text = t.toString() })
        user_change.setOnClickListener {
            userModel.doSomething()
        }
    }
}

// Fragment中的使用
class DashboardFragment : Fragment() {

    private lateinit var dashboardViewModel: DashboardViewModel

    override fun onCreateView(
            inflater: LayoutInflater,
            container: ViewGroup?,
            savedInstanceState: Bundle?
    ): View? {
        dashboardViewModel =
                ViewModelProvider(this).get(DashboardViewModel::class.java)
        val root = inflater.inflate(R.layout.fragment_dashboard, container, false)
        val textView: TextView = root.findViewById(R.id.text_dashboard)
        dashboardViewModel.text.observe(viewLifecycleOwner, Observer {
            textView.text = it
        })
        textView.setOnClickListener {
            startActivity(Intent(activity,ViewModuleActivity::class.java))
        }
        return root
    }
}

總結:viewModel的使用相對來說比較簡單,它更多的是一種思想的體現椎椰。

ViewModel的其他注意事項

1.Fragment間共享數據
因為ViewModel只會在Activity存活時厦幅,會創(chuàng)建一次,因此在同一個Activity中可以在多個Fragment中共享ViewModel中數據慨飘。

public class FragmentA extends Fragment{
       //...
      ViewModelProviders.of(getActivity()).get(AViewModel.class).getDatas().observe(this, new Observer<User>() {
            @Override
            public void onChanged(@Nullable User user) {
                  //獲取Activity中數據變化
            }
        });
}
public class FragmentB extends Fragment{
       //...
      ViewModelProviders.of(getActivity()).get(AViewModel.class).getDatas().observe(this, new Observer<User>() {
            @Override
            public void onChanged(@Nullable User user) {
                  //獲取Activity中數據變化
            }
        });
}
    //在Activity中更新數據
   ViewModelProviders.of(getActivity()).get(AViewModel.class). updateUser();

2.ViewModel絕對不要持有下列引用
1.view
2.Lifecycle
3.其他任何可能持有Activity Context的類的引用

3.ViewModel中使用Context
如果ViewModel需要Applicaiton的Context(為了獲取系統服務)确憨,該如何處理?

自定義一個類译荞,繼承自AndroidViewModel
構造器一定要有一個唯一參數-Application'的對象

class UserModel(application: Application) : AndroidViewModel(application) {

    val userLiveData = MutableLiveData<User>()
    private var mApplication: Application? = null

    init {
        userLiveData.postValue(User(1, "jack"))
        mApplication = application
    }

    fun doSomething() {
        val user = userLiveData.value?.apply {
            age = (100..500).random()
            name = "jack$age"
        }
        userLiveData.value = user
        Toast.makeText(mApplication?.applicationContext,"數據發(fā)生了改變",Toast.LENGTH_SHORT).show()
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市休弃,隨后出現的幾起案子吞歼,更是在濱河造成了極大的恐慌,老刑警劉巖塔猾,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篙骡,死亡現場離奇詭異,居然都是意外死亡丈甸,警方通過查閱死者的電腦和手機糯俗,發(fā)現死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來睦擂,“玉大人得湘,你說我怎么就攤上這事《俪穑” “怎么了淘正?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長夺欲。 經常有香客問我跪帝,道長,這世上最難降的妖魔是什么些阅? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任伞剑,我火速辦了婚禮,結果婚禮上市埋,老公的妹妹穿的比我還像新娘黎泣。我一直安慰自己,他們只是感情好缤谎,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布抒倚。 她就那樣靜靜地躺著,像睡著了一般坷澡。 火紅的嫁衣襯著肌膚如雪托呕。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天频敛,我揣著相機與錄音项郊,去河邊找鬼。 笑死斟赚,一個胖子當著我的面吹牛着降,可吹牛的內容都是我干的。 我是一名探鬼主播拗军,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼任洞,長吁一口氣:“原來是場噩夢啊……” “哼蓄喇!你這毒婦竟也來了?” 一聲冷哼從身側響起交掏,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤妆偏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后耀销,有當地人在樹林里發(fā)現了一具尸體楼眷,經...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年熊尉,在試婚紗的時候發(fā)現自己被綠了罐柳。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡狰住,死狀恐怖张吉,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情催植,我是刑警寧澤肮蛹,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站创南,受9級特大地震影響伦忠,放射性物質發(fā)生泄漏。R本人自食惡果不足惜稿辙,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一昆码、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧邻储,春花似錦赋咽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宦赠,卻和暖如春陪毡,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勾扭。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工缤骨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人尺借。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像精拟,于是被迫代替她去往敵國和親燎斩。 傳聞我的和親對象是個殘疾皇子虱歪,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345