<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [toc] # 1. 前言 官網地址:[https://developer.android.google.cn/topic/libraries/architecture/livedata](https://developer.android.google.cn/topic/libraries/architecture/livedata) 其實在使用`ViewModel`和`LifeCycle`的時候,我們已經看見了`LiveData`這個組件。在這篇博客中將繼續來了解這個組件。其特點: - `LiveData`是一種**可觀察的數據存儲器類**; - 與常規的可觀察類不同,`LiveData`**具有生命周期感知能力**。其感知能力遵循其他組件(如 `Activity`、`Fragment` 或 `Service`)的生命周期; - 感知能力可確保`LiveData`**僅更新處于活躍生命周期狀態**的應用組件觀察者;活躍的觀察者對象聲明周期處于`STARTED `或 `RESUMED` 狀態; - `LiveData`只會將更新通知給**活躍的觀察者**,非活躍觀察者不會收到更改通知; - 當觀察者組件的`Lifecycle`對象的狀態變為 `DESTROYED` 時,便可移除此觀察者,不必擔心泄露(當 `Activity `和` Fragment `的生命周期被銷毀時,系統會立即退訂它們)。 不妨再次看下這個圖: ![](https://img.kancloud.cn/6c/3b/6c3b2e3708be0b1edf21103dc9259633_1068x424.png) ## 1.1 關于觀察者模式 我們知道觀察者模式,在`Java`中提供了`Observable`和`Observer`來定義被觀察者和觀察者對象。然后對于可觀察對象可以設置觀察者,來監聽其變化。而在`Android`的`Lifecycle`包中提供了對應的`LifecycleOwner`和`LifecycleObserver`,而在`Activity`、`Fragment` 或 `Service`等組件中已經實現了`LifecycleOwner`接口,我們在使用的時候,只需要實現`LifecycleObserver`來標識類是一個觀察者,以注冊觀察。在之前的博客:[【Android Jetpack】LifeCycle](https://mengfou.blog.csdn.net/article/details/124254857)一文中也曾提到過通過: ```kotlin lifecycle.addObserver(myLocationObserver) ``` 來為`lifecycle`來設置一個觀察者對象。類似的,前面提到了:`LiveData`也是一種可觀察的數據存儲器類。故而也可以設置觀察對象,比如: ~~~kotlin // viewModel.get() 獲取的為LiveData對象 viewModel.get().observe(this, object : androidx.lifecycle.Observer<Int>{ override fun onChanged(value: Int?) { livedataText.text = viewModel.getValue().toString() } }) ~~~ # 2. LiveData 的優勢 - 確保界面符合數據狀態;`LiveData` 遵循觀察者模式。當底層數據發生變化時,`LiveData` 會通知 `Observer` 對象。您可以整合代碼以在這些 `Observer` 對象中更新界面。 - 不會發生內存泄漏;觀察者會綁定到 `Lifecycle` 對象,并在其關聯的生命周期遭到銷毀后進行自我清理。 - 不會因 `Activity` 停止而導致崩潰;如果觀察者的生命周期處于非活躍狀態,則它不會接收任何 `LiveData` 事件。 - 不再需要手動處理生命周期; - 共享資源;可以使用單例模式擴展 `LiveData` 對象以封裝系統服務,以便在應用中共享它們。`LiveData` 對象連接到系統服務一次,然后需要相應資源的任何觀察者只需觀察 `LiveData` 對象。 更加通俗來說,`LiveData`是一個持有`Activity`、`Fragment`生命周期的數據容器。當數據源發生改變的時候,可以通知觀察者。 ## 2.1 案例一:計時器效果 在`Activity`中定義一個文本,在該控件上每秒自動加一操作。且屏蔽設備配置發生改變后不影響其狀態。比如布局文件為`ConstraintLayout`下放置一個居中的`TextView`。 ### 2.1.1 實現方式一:ViewModel+LiveData - 因為需要屏蔽設備配置發生改變的影響,故而這里考慮直接使用`ViewModel`; - 考慮代碼解耦,這里使用`LiveData`來設置觀察者,也即是我們需要在`ViewModel`中設置數據類型為`LiveData`; 自定義的`ViewModel`如下: ~~~kotlin class MyNumberViewModel : ViewModel() { private var number: MutableLiveData<Int> = MutableLiveData(0) fun set(value: Int) { number.value = value } // 工作線程需要使用Post fun post(value: Int) { number.postValue(value) } fun get(): LiveData<Int> { return number } fun getValue(): Int{ return number.value?:0 } } ~~~ 因為我們需要使用`LiveData`對象來注冊觀察者對象,故而這里`get()`方法返回的是`LiveData`對象。且因為需要開啟定時任務,故而可以在工作線程完成,所以提供了`post`方法,然后在`Activity`中進行設置: ~~~kotlin class LiveDataActivity : AppCompatActivity() { private lateinit var viewModel: MyNumberViewModel private val livedataText: TextView by lazy { findViewById(R.id.livedata_text)} override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_live_data) // 獲取到ViewModel viewModel = ViewModelProvider( this, ViewModelProvider.NewInstanceFactory() ).get(MyNumberViewModel::class.java) // 為TextView設置數據 livedataText.text = viewModel.get().toString() // 開始定時任務 startTimer() // 注冊一個觀察者,監聽到ViewModel中數據的變化,如果變化執行onChanged()方法 // viewModel.get() 獲取的為LiveData對象 viewModel.get().observe(this, object : androidx.lifecycle.Observer<Int>{ override fun onChanged(value: Int?) { livedataText.text = viewModel.getValue().toString() } }) } // 定時任務 private fun startTimer(){ Timer().schedule( object : TimerTask() { override fun run() { viewModel.post(viewModel.getValue() + 1) } }, 1000, 1000, ) } } ~~~ 運行即可看見預想的效果。看完上述案例代碼之后是否會有疑惑?肯定是有的,因為這里是`LiveData`的案例,卻引入了`ViewModel`,且將`LiveData`放入了自定義的`ViewModel`類中,為什么需要這么做?`LiveData`對象本身就可以被觀察,為什么還需要放置到`ViewModel`中? 答:其實在剛開始的要求部分我已經做了引導,需要做到**屏蔽設備配置發生改變后不影響其狀態**,而很方便的`ViewModel`就可以輕松做到這一點。如果`LiveData`實例與特定的 `Activity` 或 `Fragment` 實例并沒有分離開,那么在 `Activity` 或 `Fragment` 經歷`onDestory`的時候,`LiveData`中的數據也就沒了。 且上述程序存在一個致命`Bug`,由于每次屏幕旋轉都會執行`onCreate`,故而會開啟多個定時任務,故而這里是不符合題意的。當然,可以加上標志處理,這里不再解決。 ### 2.1.2 實現方式二:configChange 當然,上述使用`ViewModel`只是一種方式,也可以配置清單文件,設置`onConfigChange`屬性,這里來嘗試寫一下: ~~~xml <activity android:name=".LiveDataActivity" android:configChanges="orientation|screenSize" android:exported="true"> ~~~ 然后將`LiveData`直接定義在`Activity`中: ~~~kotlin class LiveDataActivity : AppCompatActivity() { private val livedataText: TextView by lazy { findViewById(R.id.livedata_text) } private val liveData: MutableLiveData<Int> by lazy { MutableLiveData<Int>(0) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_live_data) // 為TextView設置數據 livedataText.text = liveData.value.toString() // 開始定時任務 startTimer() // 注冊一個觀察者,監聽到ViewModel中數據的變化,如果變化執行onChanged()方法 // viewModel.get() 獲取的為LiveData對象 liveData.observe(this) { livedataText.text = liveData.value.toString() } } override fun onConfigurationChanged(newConfig: Configuration) { super.onConfigurationChanged(newConfig) Log.e("TAG", "onConfigurationChanged: ") } // 定時任務 private fun startTimer() { Timer().schedule( object : TimerTask() { override fun run() { liveData.postValue((liveData.value ?: 0) + 1) Log.e("TAG", "run: ${liveData.value ?: 0}", ) } }, 1000, 1000, ) } } ~~~ ## 2.2 案例二:
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看