<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>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] # 1. 說明 `LifeCycle`它持有組件的生命周期狀態信息,主要用于`Activity`、`Fragment`、`Service`和`Application`的生命周期管理,其他類可以觀察到這些狀態,進而有利于代碼的解耦。而且在配置更改后可以輕松避免內存泄漏,以及將數據加載到界面中。 比如在Activity 生命周期的狀態和事件: ![](https://img.kancloud.cn/5d/1d/5d1dbe2eb837edd3908ad678b897651d_1068x424.png) # 2. Lifecycle 在`Lifecycle`中存在**兩類角色**: * 具有生命周期的組件,比如`Activity`、`Fragment`、`Service` 等任何具有生命周期的組件,通常被稱為`LifecycleOwner`,也即是被觀察者。 * `LifecycleObserver`,即觀察者,需要感知生命周期方法。 很明顯,也就是觀察者模式。由于在上述組件中已經實現了`LifecycleObserver`接口,比如在`Activity`中: ~~~java public class ComponentActivity extends androidx.core.app.ComponentActivity implements ContextAware, LifecycleOwner, ... ~~~ 并實現了其`getLifecycle`方法,故而在觀察者模式中被觀察者已經由系統實現,我們所需要做的也就是實現觀察者類,也即是自定義類,實現`LifecycleObserver`接口,然后設置觀察即可。 ## 2.1 LifecycleObserver 而該接口又只是一個空接口,即僅用作標識: ~~~java public interface LifecycleObserver { } ~~~ ## 2.2 LifecycleOwner LifecycleOwner 是一個接口,用來表示類具有`Lifecycle`。其聲明如下: ~~~java public interface LifecycleOwner { @NonNull Lifecycle getLifecycle(); } ~~~ 可以看見只有一個方法,也就是getLifecycle(), 可以通過調用Lifecycle類的addObserver()方法并傳遞觀察器的實例來添加觀察器,比如下面的代碼: ~~~kotlin class MyObserver : DefaultLifecycleObserver { ? ? override fun onResume(owner: LifecycleOwner) { ? ? ? ? connect() ? ? } ? ? override fun onPause(owner: LifecycleOwner) { ? ? ? ? disconnect() ? ? } } myLifecycleOwner.getLifecycle().addObserver(MyObserver()) ~~~ # 3. 案例 比如下面的案例: ## 3.1 案例一:使用LifeCycle解耦頁面組件 學習視頻地址:[LifeCycle](https://www.bilibili.com/video/BV1Ry4y1t7Tj?p=2&spm_id_from=pageDriver) 不使用LifeCycle的時候,通過Chronometer計時器來做一個簡單的計時操作,滿足下面條件: * 當`Activity`可見的時候,繼續計時; * 當`Activity`不可見的時候,且還沒有被Destory的時候,就暫停當前計時; ### 3.1.1 借助生命周期方法 ~~~ class MainActivity : AppCompatActivity() { // 繼承自TextView的一個計時器類 private lateinit var chronometer: Chronometer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) chronometer = findViewById(R.id.chronometer) } private var elapsedtime = 0L // 可見 override fun onResume() { super.onResume() // 設置計時器的起始時間為“當前”系統時間 // SystemClock.elapsedRealtime() 從設備開機到現在的時間 chronometer.base = SystemClock.elapsedRealtime() - elapsedtime chronometer.start() } // 不可見 override fun onStop() { super.onStop() elapsedtime = SystemClock.elapsedRealtime() - chronometer.base chronometer.stop() } } ~~~ 上面設置`chronometer.base`,主要是用于設置計時器的“當前起始時間”,主要是為了確保暫停后開始的基準時間可以略過中間暫停事件,確保計時器在`Activity`可見后可以連續計時。但是,很顯然,這樣多余了很多額外的周期函數方法,使用比較麻煩。而使用`LifeCycle`可以對其進行最大程度簡化。而且在組件化開發中,基本的原則就是:**能不麻煩別人的事情就盡量自己做**。需要暴露更少的方法來完成其功能。 ### 3.1.2 借助LifeCycle 首先封裝一下Chronometer這個類,聲明其實現了LifecycleObserver接口: ~~~ class MyChronometer: Chronometer, LifecycleObserver { constructor(context: Context?) : super(context) constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) private var elapsedtime = 0L @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun startChronometer(){ // 設置計時器的起始時間為“當前”系統時間 base = SystemClock.elapsedRealtime() - elapsedtime start() } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) fun stopChronometer(){ elapsedtime = SystemClock.elapsedRealtime() - base stop() } } ~~~ 將前面案例中的代碼添加到其中,并為其指定了對應的`Lifecycle`事件方法。對應的將`xml`中修改為我們自定義的`MyChronometer`類,然后調用: ~~~ class MainActivity1 : AppCompatActivity() { // 繼承自TextView的一個計時器類 private lateinit var chronometer: MyChronometer override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) chronometer = findViewById(R.id.chronometer) // 為Activity的lifecycle添加一個監聽 lifecycle.addObserver(chronometer) } } ~~~ 就可以看見一樣滿足要求的計時器。這兩個案例做一個簡單的對比,很明顯第二種寫法更加利于系統組件和普通組件的**代碼解耦**。這里可以總結一下上面的使用流程: * 自定義一個類,實現了`LifecycleObserver`接口; * 在`Activity`或者`Fragment`中進行添加觀察者,以**監聽**對應的生命周期函數; ## 3.2 案例二:使用LifeCycleService解耦Service組件 視頻地址:https://www.bilibili.com/video/BV1Ry4y1t7Tj?p=3&t=863.3 該案例以模擬獲取GPS為案例,具體為在后臺開啟一個Service,然后在這個Service中注冊觀察者對象,在這個觀察者對象中可以觀察到Activity的onStart、onStop等事件。也就可以自動完成進入這個Activity就開始獲取地理位置的更新,退出這個Activity就停止獲取位置。 ### 3.2.1. 基礎版本 如果獲取用戶地理位置的功能沒有獨立封裝為一個組件,那么我們如果需要考慮頁面聲明周期,那么就需要按照下面的形式,因為非自定義組件并不能主動感知聲明周期的變化。 ~~~kotlin class LocationActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<ActivityLocationBinding>( this, R.layout.activity_location ) } override fun onResume() { super.onResume() // 開始獲取用戶地理位置 startGetLocation() } override fun onPause() { super.onPause() // 停止獲取 stopGetLocation() } } ~~~ ### 3.2.2. 使用Service 上面的第一種方式明顯的缺點就是耦合度很高,所以為了減少耦合度,而又不影響對生命周期的監聽,就可以使用`LifeCycle`來進行改寫。故而我們可以自定義一個類,然后使用`LifecycleObserver`來標識這個類為`LifeCycle`的一個觀察者類,在這個類中完成自定義控件,即具體功能。 ~~~kotlin class MyLocationObserver(context: Context): LifecycleObserver { private var mCtx : Context = context private lateinit var myLocationListener: MyLocationListener private lateinit var locationManager: LocationManager @OnLifecycleEvent(Lifecycle.Event.ON_START) private fun startGetLocation(){ Log.e("TAG", "startGetLocation: ") // 獲取LocationManager locationManager = mCtx.getSystemService(Context.LOCATION_SERVICE) as LocationManager // 權限 if (ActivityCompat.checkSelfPermission( mCtx, Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission( mCtx, Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED ) { return } // 添加監聽 myLocationListener = MyLocationListener() locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000, 2f, myLocationListener) } inner class MyLocationListener: LocationListener{ override fun onLocationChanged(location: Location) { Log.e("TAG", "onLocationChanged: ${ location }" ) } } @OnLifecycleEvent(Lifecycle.Event.ON_STOP) private fun stopGetLocation(){ Log.e("TAG", "stopGetLocation: ", ) // 移除 locationManager.removeUpdates(myLocationListener) } } ~~~ 當頁面生命周期發生變化時,這些使用`@OnLifecycleEvent`標識過的方法便會被自動調用。那么在調用的時候,由于`Activity`或者`Service`均已經實現了被觀察者`LifecycleOwner`的接口,故而這里直接調用實現這個接口的`getLifecycle`方法,得到`Lifecycle`對象,然后添加觀察者: ~~~kotlin lifecycle.addObserver(MyLocationObserver(this)) ~~~ 注意到,本小節的標題為使用`Service`,這里我們可以使用比較經典的寫一個類繼承自`Service`,根據自己所使用的啟動方式,即`startService`或者`bindService`來復寫對應的`onStartCommand`或者`onBind`方法。然后在`Activity`中進行`startService`或者`bindService`。比如: ~~~kotlin class MyService: LifecycleService() { private var _observer: MyLocationObserver = MyLocationObserver(this) init { lifecycle.addObserver(_observer) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { Log.e("TAG", "onStartCommand: ") // 注冊觀察者 val myLocationObserver = MyLocationObserver(this) lifecycle.addObserver(myLocationObserver) return super.onStartCommand(intent, flags, startId) } override fun onDestroy() { super.onDestroy() lifecycle.removeObserver(_observer) } } ~~~ 然后在主`Activity`中啟動服務: ~~~kotlin class LocationActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<ActivityLocationBinding>( this, R.layout.activity_location ) // 啟動服務 startService(Intent().apply { setClass(this@LocationActivity, MyService::class.java) }) } } ~~~ 運行可以看見結果: ![](https://img.kancloud.cn/fb/c0/fbc019c92d0449bc3ae8442585c5d1da_1805x200.png) 然后可以使用`adb devices`查看一下設備: ![](https://img.kancloud.cn/3d/62/3d6216ca220ac7ddcedeee05270517ed_569x79.png) 然后可以使用`adb`命令修改模擬位置: ``` adb -s emulator-5554 emu geo fix 101.49612 41.24010 ``` ![](https://img.kancloud.cn/e2/ec/e2ec9623b786cf47182f780fe3b53544_984x54.png) 就可以發現日志進行了更新: ![](https://img.kancloud.cn/b1/a1/b1a18425fb61ed8678c4f6148a1068ce_1454x313.png) ## 3.3. 案例三:監聽應用程序的生命周期 在`LifeCycle`中提供了`ProcessLifecycleOwner`來實現監聽應用程序的聲明周期。同樣的,這里還是自定義一個類,繼承自`LifecycleObserver`: ~~~kotlin class MyApplicationObserver : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_CREATE) private fun onCreate() { Log.e("TAG", "application onCreate.") } @OnLifecycleEvent(Lifecycle.Event.ON_START) private fun onStart() { Log.e("TAG", "application onStart.") } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) private fun onResume() { Log.e("TAG", "application onResume.") } } ~~~ 然后在`Activity`中使用: ~~~ class LocationActivity: AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val binding = DataBindingUtil.setContentView<ActivityLocationBinding>( this, R.layout.activity_location ) // 添加應用程序生命周期觀察者對象 ProcessLifecycleOwner.get().lifecycle.addObserver(MyApplicationObserver()) } } ~~~ 就可以監聽到應用程序的生命周期變化。 ![](https://img.kancloud.cn/59/5b/595b905a89dda20f85b5a031502d3a58_884x83.png) - ProcessLifecycleOwner是針對整個應用程序的監聽,與Activity數量無關; - Lifecycle.Event.ON_CREATE只會被調用一次,而Lifecycle.Event.ON_DESTROY永遠不會被調用。
                  <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>

                              哎呀哎呀视频在线观看