Android lifecycle 使用詳解

說在前面

本次推出 Android Architecture Components 系列文章,目前寫好了四篇,主要是關於 lifecycle,livedata 的使用和源碼分析,其他的 Navigation, Paging library,Room,WorkMannager 等春節結束以後會更新,歡迎關注個人公衆號,有更新的話會第一時間會在公衆號上面通知。javascript

Android lifecycle 使用詳解java

Android LiveData 使用詳解android

Android lifecyle 源碼解剖git

Android livedata 源碼解剖github

github sample 地址: ArchiteComponentsSampleide

Android 技術人,一位不羈的碼農。源碼分析

Android 技術人


簡介

Architecture Components ui

lifecycle 是 2107 年 google 大會推出來的,它屬於 architecture compoment 裏面的一個組件,它能夠幹什麼用呢? 簡單得來講,它能夠用來檢查 Activity 的生命週期,而沒必要強依賴 Activity。this


爲何要引進 lifecycle

舉一下咱們最經常使用的 MVP 例子,沒引進 lifecycle 以前,咱們須要在 Activity 或者 Fragment 銷燬的時候,即 onDestroy 的時候手動調用 onDestroy 方法,這裏會帶來一些問題,每一次在 Activity 或者 Fragment 銷燬的燒開後都要調用 presenter.destory() 方法,這樣的代碼枯燥,毫無心義。google

class MyPresenter{
    public MyPresenter() {
    }

    void create() {
        //do something
    }

    void destroy() {
        //do something
    }
}

class MyActivity extends AppCompatActivity {
    private MyPresenter presenter;

    public void onCreate(...) {
        presenter= new MyPresenter ();
        presenter.create();
    }

    public void onDestroy() {
        super.onDestroy();
        presenter.destory();
    }
}
複製代碼

固然咱們也能夠定義一些 IBasePresenter 的接口,在 BaseActivity 的時候調用 IBasePresenter 的 onDestroy 方法,這樣也確實能作到。只不過稍微繁瑣一點。

那若是是別的類的呢,好比 MediaCompoment,在 Activity 的時候,咱們須要銷燬一些資源,按照傳統的方法,咱們仍是須要在 Activity onDestroy 的時候手動調用 onDestroy 方法。那有沒有更好的方法呢?固然是有的,lifecycle 就能夠解決這個問題。接下來,咱們先來看一下 Lifycycle 的基本使用。


Lifycycle 的基本使用

  1. 引入相關的依賴包

Lifecycle 已是穩定版,它包含在 support library 26.1.0 及以後的依賴包中,若是咱們的項目基於這些依賴包,那麼不須要額外的引用。

// ViewModel and LiveData
implementation "android.arch.lifecycle:extensions:1.1.0"
// alternatively, just ViewModel
implementation "android.arch.lifecycle:viewmodel:1.1.0"
// alternatively, just LiveData
implementation "android.arch.lifecycle:livedata:1.1.0"
複製代碼

support library在26.1.0 以前,lifecycle 並無集成進去,須要咱們引入另外的包。

implementation "android.arch.lifecycle:extensions:1.0.0-alpha4"
複製代碼
  1. 使用

這裏一樣分爲幾種狀況

  1. support library 26.1.0 以後,且繼承 FragmentActivity,那麼咱們直接調用 getLifecycle().addObserver 方法便可,當 Activity 的生命週期變化的時候,將會回調 onStateChanged 的方法,狀態分別是一一對應的
public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
   
        getLifecycle().addObserver(new GenericLifecycleObserver() {

            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                Log.d(TAG, "onStateChanged: event =" + event);
            }
        });
    }
	
}
複製代碼
  1. support library 26.1.0 以後,不是繼承 FragmentActivity,只是簡單地繼承 Actiivty
public class SimpleLifecycleActivity extends Activity implements LifecycleOwner {

    private static final String TAG = "SimpleLifecycleActivity";
    private LifecycleRegistry mLifecycleRegistry;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple_lifecycle);
        mLifecycleRegistry = new LifecycleRegistry(this);
        mLifecycleRegistry.markState(Lifecycle.State.CREATED);
        getLifecycle().addObserver(new GenericLifecycleObserver() {

            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                Log.d(TAG, "onStateChanged: event =" + event);
            }
        });
    }

    @Override
    protected void onStart() {
        super.onStart();
        mLifecycleRegistry.markState(Lifecycle.State.STARTED);
    }

    @NonNull
    @Override
    public Lifecycle getLifecycle() {
        return mLifecycleRegistry;
    }

}

複製代碼
  1. support library 26.1.0 以前

(如今的 support library 基本都在 26.1.0 以後了,這個能夠忽略)

第一步:實現 LifecycleOwner 接口,並返回響應的 Lifecycle

public interface LifecycleOwner {
    /** * Returns the Lifecycle of the provider. * * @return The lifecycle of the provider. */
    @NonNull
    Lifecycle getLifecycle();
}
複製代碼

第二步:在 Activity 生命週期變化的時候,調用 mLifecycleRegistry.handleLifecycleEvent 方法,分發相應的生命週期。

第三步:調用 Lifecycle 的 addObserver 方法添加相應的 Observer。

代碼以下

public class MainActivity extends AppCompatActivity implements LifecycleOwner {

    private LifecycleRegistry mRegistry;

    private static final String TAG = "MainActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRegistry = new LifecycleRegistry(this);
        mRegistry.markState(Lifecycle.State.CREATED);
        getLifecycle().addObserver(new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
                Log.d(TAG, "onStateChanged:event =" + event);
            }

            @Override
            public Object getReceiver() {
                return null;
            }
        });

    }

    @Override
    protected void onStart() {
        super.onStart();
        mRegistry.markState(Lifecycle.State.STARTED);
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mRegistry.markState(Lifecycle.State.RESUMED);
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
    }

    @Override
    protected void onStop() {
        super.onStop();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mRegistry.markState(Lifecycle.State.DESTROYED);
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
    }

    @Override
    public Lifecycle getLifecycle() {
        return mRegistry;
    }
}

複製代碼

總結

咱們回過頭來看一下咱們上面提出的問題?

MediaCompoment 在 Activity ondestroy 的時候,咱們須要銷燬一些資源,用傳統的方法,咱們須要在 Activity onDestroy 的時候手動調用 onDestroy 方法。這樣會存在一個問題,調用者必須知道比較清楚得知道 MediaCompoment 的設計,不然可能會忘記調用 onDestroy 的方法。

那有沒有一種方法, 當 Activity 生命週期變化的時候,MediaCompoment 自身可以檢測到 Activity 的 生命週期變化,從而作相應的處理。

答案固然是有的,使用 lifycycle。

public class MediaCompoment {
    private static final String TAG = "MediaCompoment";

    private final LifecycleOwner mLifecycleOwner;

    public MediaCompoment(LifecycleOwner lifecycleOwner) {
        mLifecycleOwner = lifecycleOwner;
        mLifecycleOwner.getLifecycle().addObserver(new GenericLifecycleObserver() {
            @Override
            public void onStateChanged(LifecycleOwner source, final Lifecycle.Event event) {
                if (event == Lifecycle.Event.ON_CREATE) {
                    onCreate();
                } else if (event == Lifecycle.Event.ON_START) {
                    onStart();
                } else if (event == Lifecycle.Event.ON_RESUME) {
                    onResume();
                } else if (event == Lifecycle.Event.ON_PAUSE) {
                    onPause();
                } else if (event == Lifecycle.Event.ON_STOP) {
                    onStop();
                } else if (event == Lifecycle.Event.ON_DESTROY) {
                    onDestroy();
                }
            }
        });
    }

    public void onCreate() {
        Log.d(TAG, "onCreate:");
    }

    public void onStart() {
        Log.d(TAG, "onStart:");
    }

    public void onResume() {
        Log.d(TAG, "onResume:");
    }

    public void onPause() {
        Log.d(TAG, "onPause:");
    }

    public void onStop() {
        Log.d(TAG, "onStop:");
    }

    public void onDestroy() {
        Log.d(TAG, "onDestroy:");
    }
}
複製代碼

小結:

  1. lifycycle 實際上是用觀察者模式實現的,當 Activity 生命週期變化的時候,通知相應的 Observers 即觀察者。
  2. 使用 lifecycle,咱們能夠將釋放資源的動做內聚在自身,減小與調用者之間的耦合。

下一篇博客:Android LiveData 使用詳解

相關文章
相關標籤/搜索