Android 架構組件簡單小結

Android官方提供了一組架構組件(Android Architecture Components)用來幫助開發者創建健壯、易測試和可維護的apps。包括Lifecycle、LiveData、ViewModel和Room Persistence Library。

Lifecycle

Lifecycle是一個包含組件(比如Activity或者Fragment)生命週期信息的類。Lifecycle用兩種枚舉來表示相關聯的生命週期的狀態。

  • Event
  • State
    這裏寫圖片描述

    LifecycleObserver通過對方法添加註解的方式來監聽組件的生命週期。

public class MyObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
    public void onResume() {
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void onPause() {
    }
}
aLifecycleOwner.getLifecycle().addObserver(new MyObserver());

LifecycleOwner

LifecycleOwner是一個只包含getLifecycle()方法的接口,表示這這個一個包含Lifecycle。LifecycleActivity 和 LifecycleFragment已經實現了這個接口,也可以在自定義的類中實現這個接口,不過這時候需要自己發送生命週期事件。

/**
 * Activity that implements {@link LifecycleOwner}.
 * <p>
 * This class is a temporary implementation detail until Lifecycles are integrated with support
 * library.
 */
public class LifecycleActivity extends FragmentActivity implements LifecycleRegistryOwner {

    private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);

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

ViewModel

ViewModel是用來存儲UI相關的數據,使得數據不受配置變化影響(比如旋轉屏幕)。

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);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        itemSelector.setOnClickListener(item -> {
            model.select(item);
        });
    }
}

public class DetailFragment extends LifecycleFragment {
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        model.getSelected().observe(this, { item ->
           // update UI
        });
    }
}

上面的例子可以看出ViewModel可以很方便的實現在Fragment之間傳遞數據。
ViewModel在配置信息變化時仍然保存着信息,因此它不應該包含任何的context相關的引用(需要applicationContext可以繼承AndroidViewModel)。同時ViewModel也是有相應的生命週期,在我們自己的Activity銷燬的時候會回調 onCleared()來清除資源。
這裏寫圖片描述

ViewModel vs SavedInstanceState

   ViewModels提供了一種方便的方法來在配置更改中保留數據,但如果應用程序被操作系統殺死,則不會持久保存數據。
   例如,如果用戶離開應用程序並在幾個小時後返回,該進程將在此期間被殺死,而Android操作系統將從被保存的狀態恢復活動。所有框架組件(視圖、活動、片段)都使用保存的實例狀態機制來保存它們的狀態,所以大多數情況下,您不需要做任何事情。您可以使用onSaveInstanceState回調將自定義數據添加到這個bundle中。
   通過onSaveInstanceState保存的數據是保存在系統進程內存並Android操作系統允許你只保留少量的數據,所以這不是保存應用程序實際數據的好地方。

LiveData

LiveData是一個保存可以被觀察的數據類,包含app組件的lifecycle。
如果Observer的生命週期處於STARTED or RESUMED,LiveData認爲觀察者處於活動狀態。

public class LocationLiveData extends LiveData<Location> {
    private static LocationLiveData sInstance;
    private LocationManager locationManager;

    @MainThread
    public static LocationLiveData get(Context context) {
        if (sInstance == null) {
            sInstance = new LocationLiveData(context.getApplicationContext());
        }
        return sInstance;
    }

    private SimpleLocationListener listener = new SimpleLocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            setValue(location);
        }
    };

    private LocationLiveData(Context context) {
        locationManager = (LocationManager) context.getSystemService(
                Context.LOCATION_SERVICE);
    }

    @Override
    protected void onActive() {
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);
    }

    @Override
    protected void onInactive() {
        locationManager.removeUpdates(listener);
    }
}
  • onActive()
    意味着LiveData已經有了處於活動狀態的觀察者
  • onInactive()
    意味着LiveData已經沒有觀察者或者沒有觀察者處於活動狀態
  • setValue()
    更新LiveData實例並通知觀察者發生了改變
public class MyFragment extends LifecycleFragment {
    public void onActivityCreated (Bundle savedInstanceState) {
        Util.checkUserStatus(result -> {
            if (result) {
                LocationLiveData.get(getActivity()).observe(this, location -> {
                   // update UI
                });
            }
        });
  }
}

Transformations of LiveData

  • Transformations.map()
LiveData<User> userLiveData = ...;
LiveData<String> userName = Transformations.map(userLiveData, user -> {
    user.name + " " + user.lastName
});
  • Transformations.switchMap()
private LiveData<User> getUser(String id) {
  ...;
}

LiveData<String> userId = ...;
LiveData<User> user = Transformations.switchMap(userId, id -> getUser(id) );

只要有active狀態的觀察者,Transformations可以讓LiveData轉換自動進行,這種延遲計算的性質允許隱式地傳遞與生命週期相關的行爲,而不需要添加顯式的調用或依賴。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章