Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Architecture Components - Lifecycle library

Architecture Components - Lifecycle library

a slide of architecture components about lifecycle library.

Masaki Ogata

May 29, 2017
Tweet

More Decks by Masaki Ogata

Other Decks in Programming

Transcript

  1. CA.apk #3 Google I/O 2017 ใࠂձ @CyberAgent
    Masaki Ogata
    ArchitectureComponents
    Lifecycle library :)

    View Slide

  2. ࣗݾ঺հ
    Masaki Ogata
    CyberAgent, Inc. / AbemaTV, Inc.
    ogaclejapan
    @ogaclejapan
    New

    View Slide

  3. ͍ͭʹ…
    ॳ౰બ͠·ͨ͠

    View Slide

  4. ॳI/O ŝŦŝŦŝŦŝŦᴸᴸᴸ ƅ㱼ƅ㲇 ƅ㱼ƅ㲇ƅ㱼ƅ)㲇ƅ㱼ƅ)ᴸᴸᴸᴸ!!

    View Slide

  5. Google Keynote

    View Slide

  6. Google Keynote

    View Slide

  7. What’s new for Android TV

    View Slide

  8. Single Codebase, Two Apps with Flutter and Firebase

    View Slide

  9. Google Play Awards

    View Slide

  10. Google Play Awards

    View Slide

  11. View Slide

  12. View Slide

  13. allprojects {
    repositories {
    jcenter()
    maven { url 'https://maven.google.com' }
    }
    }
    dependencies {
    compile "android.arch.lifecycle:runtime:1.0.0-alpha1"
    compile "android.arch.lifecycle:extensions:1.0.0-alpha1"
    annotationProcessor "android.arch.lifecycle:compiler:
    1.0.0-alpha1"
    }
    1. Add the Google Maven repository
    2. Add Architecture Components - Lifecycle

    View Slide

  14. Handling Lifecycles

    View Slide

  15. ϥΠϑαΠΫϧΛ΋ͭ͜ͱΛࣔ͢ΠϯλϑΣʔε
    • LifecycleOwner
    public interface LifecycleOwner {
    Lifecycle getLifecycle();
    }
    • LifecycleRegistryOwner (※Temporary)
    public interface LifecycleRegistryOwner extends
    LifecycleOwner {
    @Override
    LifecycleRegistry getLifecycle();
    }

    View Slide

  16. ݱঢ়Ͱ͸LifecycleActivity, LifecycleFragment,
    LifecycleServiceΫϥε͕ϥΠϒϥϦ಺ʹ༻ҙ͞Ε͍ͯΔ
    public class LifecycleActivity
    extends FragmentActivity implements LifecycleRegistryOwner {
    private final LifecycleRegistry mRegistry = new
    LifecycleRegistry(this);
    @Override
    public LifecycleRegistry getLifecycle() {
    return mRegistry;
    }
    }
    ※Alpha൛ͩͱAppCompatActivity൛͸࣮૷͍ͯ͠ͳ͍

    View Slide

  17. AppCompatActivityͰLifecycleΛࢼ͍ͨ͠ਓ͸ࣗલͰ
    public class LifecycleCompatActivity
    extends AppCompatActivity implements LifecycleRegistryOwner
    {
    private final LifecycleRegistry mRegistry = new
    LifecycleRegistry(this);
    @Override
    public LifecycleRegistry getLifecycle() {
    return mRegistry;
    }
    }

    Ϋϥε಺ͷ࣮૷ίʔυ͸LifecycleActivityͱશ͘ಉ͡ɻ

    ͜Ε͚ͩͰࣗಈతʹϥΠϑαΠΫϧʹԠͯͪ͡ΌΜͱಈ͘

    View Slide

  18. ϥΠϑαΠΫϧΛ؍ଌ͢ΔͨΊͷΠϯλϑΣʔε
    • LifecycleObserver
    public interface LifecycleObserver {
    }

    View Slide

  19. ϥΠϑαΠΫϧΛ؍ଌ͢ΔͨΊͷΠϯλϑΣʔε
    • LifecycleObserver
    public interface LifecycleObserver {
    }
    public class FooObserver implements LifecycleObserver {
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() { /* Start something. */ }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() { /* Stop something. */ }
    }

    View Slide

  20. ͋ͱ͸LifecycleOwnerͷLifecycleΫϥεʹadd͢Δ͚ͩ
    public class FooActivity extends LifecycleActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    getLifecycle().addObserver(new FooObserver());
    }
    }

    View Slide

  21. ͋ͱ͸LifecycleOwnerͷLifecycleΫϥεʹadd͢Δ͚ͩ
    public class FooActivity extends LifecycleActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ...
    getLifecycle().addObserver(new FooObserver());
    }
    }
    FooActivity: ⇠ onStart [0ms]
    FooObserver: Start something.
    FooActivity: ⇢ onResume()
    ...
    FooActivity: ⇠ onPause [0ms]
    FooObserver: Stop something.
    FooActivity: ⇢ onStop()
    ActivityͷϥΠϑαΠΫϧʹϩά
    Λ࢓ࠐΜͰ࣮ߦͯ͠ΈΔͱ…

    View Slide

  22. “Lifecycle-aware components”
    public class FooObserver implements LifecycleObserver {
    public FooObserver(Lifecycle lifecycle) {
    ...
    this.lifecycle.addObserver(this);
    }
    @OnLifecycleEvent(Lifecycle.Event.ON_START)
    void start() { /* Start something. */ }
    @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
    void stop() { /* "Stop something." */ }
    @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
    void cleanup() { lifecycle.removeObserver(this); }
    }

    View Slide

  23. LifecycleΫϥε
    public abstract class Lifecycle {
    public abstract void addObserver(LifecycleObserver
    observer);
    public abstract void removeObserver(LifecycleObserver
    observer);
    public abstract State getCurrentState();
    public enum Event {
    ON_CREATE, ON_START, ...ON_ANY
    }
    public enum State {
    DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;
    public boolean isAtLeast(State state) {
    return compareTo(state) >= 0;
    }
    }
    }

    View Slide

  24. LifecycleΫϥε
    public abstract class Lifecycle {
    public abstract void addObserver(LifecycleObserver
    observer);
    public abstract void removeObserver(LifecycleObserver
    observer);
    public abstract State getCurrentState();
    public enum Event {
    ON_CREATE, ON_START, ...ON_ANY
    }
    public enum State {
    DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED;
    public boolean isAtLeast(State state) {
    return compareTo(state) >= 0;
    }
    }
    }

    View Slide

  25. https://developer.android.com/topic/libraries/architecture/lifecycle.html
    class MyLocationListener implements LifecycleObserver {
    public void enable() {
    enabled = true;
    if (lifecycle.getState().isAtLeast(STARTED)) {
    // connect if not connected
    }
    }

    View Slide

  26. Deep dive into Lifecycles

    View Slide

  27. 1. LifecycleObserverͷ಺෦࣮૷͸ʁ

    View Slide

  28. AnnotationProcessorʹΑΓࣗಈੜ੒͞ΕͨFooObserver
    public class FooObserver_LifecycleAdapter implements
    GenericLifecycleObserver {
    final FooObserver mReceiver;
    ...
    @Override
    public void onStateChanged(LifecycleOwner owner,
    Lifecycle.Event event) {
    if (event == Lifecycle.Event.ON_START) {
    mReceiver.start();
    }
    if (event == Lifecycle.Event.ON_STOP) {
    mReceiver.stop();
    }
    }
    }
    ※GenericLifecycleObserver͸@hideͳΫϥε

    View Slide

  29. LifecycleRegistryΫϥε
    public class LifecycleRegistry extends Lifecycle {
    @Override
    public void addObserver(LifecycleObserver observer) {
    ObserverWithState observerWithState = new
    ObserverWithState(observer);
    mObserverSet.putIfAbsent(observer,
    observerWithState);
    observerWithState.sync();
    }
    ...
    class ObserverWithState {
    private State mObserverCurrentState = INITIALIZED;
    private GenericLifecycleObserver mCallback;
    ObserverWithState(LifecycleObserver observer) {
    mCallback = Lifecycling.getCallback(observer);
    }
    }

    View Slide

  30. LifecycleRegistryΫϥε
    public class LifecycleRegistry extends Lifecycle {
    @Override
    public void addObserver(LifecycleObserver observer) {
    ObserverWithState observerWithState = new
    ObserverWithState(observer);
    mObserverSet.putIfAbsent(observer,
    observerWithState);
    observerWithState.sync();
    }
    ...
    class ObserverWithState {
    private State mObserverCurrentState = INITIALIZED;
    private GenericLifecycleObserver mCallback;
    ObserverWithState(LifecycleObserver observer) {
    mCallback = Lifecycling.getCallback(observer);
    }
    }

    View Slide

  31. LifecyclingΫϥε
    class Lifecycling {
    static GenericLifecycleObserver getCallback(Object object)
    {
    ...
    final Class> klass = object.getClass();
    ...
    cachedConstructor =
    getGeneratedAdapterConstructor(klass);
    ...
    return new ReflectiveGenericLifecycleObserver(object);
    ...
    static String getAdapterName(String className) {
    return className.replace(".", "_") +
    "_LifecycleAdapter";
    }

    View Slide

  32. 2. Lifecycle.Eventͷൃ৴͸ҰମͲ͔͜Βʁ

    View Slide

  33. AndroidManifest (packaged)ʹո͛͠ͳprovider͕…


    ...
    android:name="android.arch.lifecycle.LifecycleRuntimeTroja
    nProvider"
    android:exported="false"
    android:multiprocess="true"
    android:authorities="com.ogaclejapan.samples.lifecycle-
    trojan" />


    (*´ŋωŋ`)̾̌˓( ͤΊͯެࣜυΩϡϝϯτʹॻ͍ͯ͘ΕΑ͒͒ɻɻɻ)

    View Slide

  34. LifecycleRuntimeTrojanProviderΫϥε
    public class LifecycleRuntimeTrojanProvider extends
    ContentProvider {
    @Override
    public boolean onCreate() {
    LifecycleDispatcher.init(getContext());
    ProcessLifecycleOwner.init(getContext());
    return true;
    }
    ...
    Firebase͕ར༻͍ͯ͠ΔContentProviderΛར༻ͨ͠ॳظԽHack
    ʢ҉໧తʹApplicationͷonCreateΑΓ΋ઌʹॳظԽΛ࣮ߦͰ͖Δʣ
    ʮHow does Firebase initialize on Android?ʯ
    https://firebase.googleblog.com/2016/12/how-does-firebase-initialize-on-android.html

    View Slide

  35. LifecycleDispatcherΫϥεͰ΍͍ͬͯΔ͜ͱʢͬ͘͟Γʣ
    • initॲཧͰActivityLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onActivityCreatedͰ”ReportFragment”ͷ௥Ճͱ
    FragmentLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onFragmentCreatedͰFragment͕
    LifecycleRegistryOwnerΛ࣮૷͍ͯ͠Ε
    ͹”DestructionReportFragment”Λ௥Ճ
    • ֤LifecycleCallbacks಺ͰLifecycleRegistryOwnerΛ࣮૷
    ͍ͯ͠Ε͹LifecycleRegistryʹରͯ͠”markState()”
    ͱ”handleLifecycleEvent()”ͷߋ৽ΛҰ෦୲͏

    View Slide

  36. LifecycleDispatcherΫϥεͰ΍͍ͬͯΔ͜ͱʢͬ͘͟Γʣ
    • initॲཧͰActivityLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onActivityCreatedͰ”ReportFragment”ͷ௥Ճͱ
    FragmentLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onFragmentCreatedͰFragment͕
    LifecycleRegistryOwnerΛ࣮૷͍ͯ͠Ε
    ͹”DestructionReportFragment”Λ௥Ճ
    • ֤LifecycleCallbacks಺ͰLifecycleRegistryOwnerΛ࣮૷
    ͍ͯ͠Ε͹LifecycleRegistryʹରͯ͠”markState()”
    ͱ”handleLifecycleEvent()”ͷߋ৽ΛҰ෦୲͏

    View Slide

  37. LifecycleDispatcherΫϥεͰ΍͍ͬͯΔ͜ͱʢͬ͘͟Γʣ
    • initॲཧͰActivityLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onActivityCreatedͰ”ReportFragment”ͷ௥Ճͱ
    FragmentLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onFragmentCreatedͰFragment͕
    LifecycleRegistryOwnerΛ࣮૷͍ͯ͠Ε
    ͹”DestructionReportFragment”Λ௥Ճ
    • ֤LifecycleCallbacks಺ͰLifecycleRegistryOwnerΛ࣮૷
    ͍ͯ͠Ε͹LifecycleRegistryʹରͯ͠”markState()”
    ͱ”handleLifecycleEvent()”ͷߋ৽ΛҰ෦୲͏

    View Slide

  38. LifecycleDispatcherΫϥεͰ΍͍ͬͯΔ͜ͱʢͬ͘͟Γʣ
    • initॲཧͰActivityLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onActivityCreatedͰ”ReportFragment”ͷ௥Ճͱ
    FragmentLifecycleCallbacks΁ίʔϧόοΫొ࿥
    • onFragmentCreatedͰFragment͕
    LifecycleRegistryOwnerΛ࣮૷͍ͯ͠Ε
    ͹”DestructionReportFragment”Λ௥Ճ
    • ֤LifecycleCallbacks಺ͰLifecycleRegistryOwnerΛ࣮૷
    ͍ͯ͠Ε͹LifecycleRegistryʹରͯ͠”markState()”
    ͱ”handleLifecycleEvent()”ͷߋ৽ΛҰ෦୲͏

    View Slide

  39. ReportFragmentΫϥε
    public class ReportFragment extends Fragment {
    public void onActivityCreated(Bundle savedInstanceState)
    {
    ...
    dispatch(Lifecycle.Event.ON_CREATE);
    }
    ...
    private void dispatch(Lifecycle.Event event) {
    if (getActivity() instanceof LifecycleRegistryOwner)
    {
    ((LifecycleRegistryOwner)
    getActivity()).getLifecycle().handleLifecycleEvent(event);
    }
    }
    LifecycleRegistryOwnerΛ࣮૷ͨ͠Activity΁ͷϥΠϑαΠΫϧมߋ
    Πϕϯτ͸͢΂ͯReportFragment಺Ͱݺ͹Ε͍ͯΔ

    View Slide

  40. ͏ʔΜɺ૝૾Ҏ্ʹཪͰ৭ʑ΍ͬͯͨɻɻ

    View Slide

  41. LiveData

    View Slide

  42. LiveDataΫϥε
    • ஋ͷߋ৽Λ҆શʹObserver΁௨஌Մೳ

    -> LifecycleOwnerͷState͕STARTED or RESUMED࣌ͷΈ௨஌
    • Lifecycle-aware components. 

    -> LifecycleOwnerͷState͕DESTROYED࣌͸observerΛࣗಈղআ
    public abstract class LiveData {
    @MainThread
    public void observe(LifecycleOwner owner, Observer
    observer) { ... }
    protected void postValue(T value) { ... }
    @MainThread
    protected void setValue(T value) { ... }
    public T getValue() { ... }
    ...
    }

    View Slide

  43. LiveDataͷ࢓૊Έ
    State: STARTED or RESUMED
    State: CREATED
    Observer LiveData
    setValue(“Foo”) : version = 0
    observe()
    onChange(“Foo”)
    setValue(“Bar”) : version = 1
    pending
    onChange(“Bar”)
    lastVersion = 0
    lastVersion = 1
    setValue(“CA”) : version = 2
    lastVersion = -1 initial : version = -1
    setValue(“apk”) : version = 3
    onChange(“apk”)
    lastVersion = 3
    pending
    ※version͕ಉ͡ͳͷͰ௨஌͠ͳ͍

    View Slide

  44. MutableLiveDataΫϥε
    public class MutableLiveData extends LiveData {
    @Override
    public void postValue(T value) {
    super.postValue(value);
    }
    @Override
    public void setValue(T value) {
    super.setValue(value);
    }
    }
    • postValue() / setValue()Λpublicείʔϓ΁มߋ

    -> ObservableField΍BehaviorSubjectΈ͍ͨͳ஋ͷมߋݕ஌͕Ͱ
    ͖ΔϓϩύςΟͱͯ͠࢖͑ͦ͏

    View Slide

  45. TimerLiveDataΫϥε (Custom)
    public class TimerLiveData extends LiveData {
    private final Runnable TimeUpdater = new Runnable() {
    @Override
    public void run() {
    setValue(elapsedTime += 1000L);
    handler.postDelayed(TimeUpdater, 1000L);
    }
    };
    private final Handler handler = new Handler();
    private long elapsedTime = 0L;
    @Override
    protected void onActive() {
    handler.postDelayed(TimeUpdater, 1000L);
    }
    @Override
    protected void onInactive() {
    handler.removeCallbacks(TimeUpdater);
    }
    }

    View Slide

  46. TimerLiveDataΫϥε (Custom)
    public class TimerLiveData extends LiveData {
    private final Runnable TimeUpdater = new Runnable() {
    @Override
    public void run() {
    setValue(elapsedTime += 1000L);
    handler.postDelayed(TimeUpdater, 1000L);
    }
    };
    private final Handler handler = new Handler();
    private long elapsedTime = 0L;
    @Override
    protected void onActive() {
    handler.postDelayed(TimeUpdater, 1000L);
    }
    @Override
    protected void onInactive() {
    handler.removeCallbacks(TimeUpdater);
    }
    }

    View Slide

  47. LiveData userName =
    Transformations.map(userLiveData, user -> {
    user.name + " " + user.lastName
    });
    Transformations
    MediatorLiveData
    https://developer.android.com/reference/android/arch/lifecycle/MediatorLiveData.html
    https://developer.android.com/reference/android/arch/lifecycle/Transformations.html
    -> ಠࣗͳTransformationsΛ৽ͨʹఆٛ͢Δͱ͖ʹ࢖͑Δ
    -> LiveDataͷ஋ΛՃ޻͢Δ (ݱঢ়͸map, switchMapͷΈ)

    View Slide

  48. ViewModel

    View Slide

  49. ViewModelΫϥε
    public abstract class ViewModel {
    protected void onCleared() {
    }
    }
    ViewModelProviders.of(activity)
    .get(FooViewModel.class)
    ViewModelStores.of(activity)
    HolderFragmentੜ੒

    -> setRetainInstance(true)

    View Slide

  50. https://speakerdeck.com/ogaclejapan/how-to-keep-data-between-orientation-changes

    View Slide

  51. ViewModelΫϥεར༻࣌ͷ஫ҙ఺
    • Activity࠶ੜ੒Λލ͍Ͱσʔλ͕อ࣋͞ΕΔͷͰɺActivity΍
    ViewɺResourceͳͲΛอ࣋͢ΔͱϝϞϦϦʔΫ͢Δ :(
    Ͳ͏ͯ͠΋ViewModel಺ͰContextΛ࢖͍͍ͨͱ͖ʹ͸Application
    ΫϥεΛอ࣋͢ΔAndroidViewModelΛ࢖͍·͠ΐ͏
    public class AndroidViewModel extends ViewModel {
    private Application mApplication;
    public AndroidViewModel(Application application) {
    mApplication = application;
    }
    public T getApplication() {
    return (T) mApplication;
    }
    }

    View Slide

  52. Architecture componentsͰਪ঑͞ΕΔΞʔΩςΫνϟ
    https://developer.android.com/topic/libraries/architecture/guide.html#the_final_architecture

    View Slide

  53. ࢀߟࢿྉ

    View Slide

  54. • ެࣜΨΠυ
    https://developer.android.com/topic/libraries/architecture/index.html
    • ެࣜαϯϓϧ
    https://github.com/googlesamples/android-architecture-components
    Architecture Components ࢀߟϦϯΫ
    • I/O ηογϣϯಈը
    Architecture Components - Introduction

    https://www.youtube.com/watch?v=FrteWKKVyzI
    Architecture Components - Solving the Lifecycle Problem

    https://www.youtube.com/watch?v=bEKNi1JOrNs

    View Slide

  55. ࠓޙʹظ଴ʂʂ

    View Slide