Save 37% off PRO during our Black Friday Sale! »

Architecture Components - Lifecycle library

Architecture Components - Lifecycle library

a slide of architecture components about lifecycle library.

9f4db21673dc0e7cbc313df8310309fb?s=128

Masaki Ogata

May 29, 2017
Tweet

Transcript

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

    Lifecycle library :)
  2. ࣗݾ঺հ Masaki Ogata CyberAgent, Inc. / AbemaTV, Inc. ogaclejapan @ogaclejapan

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

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

  5. Google Keynote

  6. Google Keynote

  7. What’s new for Android TV

  8. Single Codebase, Two Apps with Flutter and Firebase

  9. Google Play Awards

  10. Google Play Awards

  11. None
  12. None
  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
  14. Handling Lifecycles

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

    • LifecycleRegistryOwner (※Temporary) public interface LifecycleRegistryOwner extends LifecycleOwner { @Override LifecycleRegistry getLifecycle(); }
  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൛͸࣮૷͍ͯ͠ͳ͍
  17. AppCompatActivityͰLifecycleΛࢼ͍ͨ͠ਓ͸ࣗલͰ public class LifecycleCompatActivity extends AppCompatActivity implements LifecycleRegistryOwner { private

    final LifecycleRegistry mRegistry = new LifecycleRegistry(this); @Override public LifecycleRegistry getLifecycle() { return mRegistry; } } Ϋϥε಺ͷ࣮૷ίʔυ͸LifecycleActivityͱશ͘ಉ͡ɻ
 ͜Ε͚ͩͰࣗಈతʹϥΠϑαΠΫϧʹԠͯͪ͡ΌΜͱಈ͘
  18. ϥΠϑαΠΫϧΛ؍ଌ͢ΔͨΊͷΠϯλϑΣʔε • LifecycleObserver public interface LifecycleObserver { }

  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. */ } }
  20. ͋ͱ͸LifecycleOwnerͷLifecycleΫϥεʹadd͢Δ͚ͩ public class FooActivity extends LifecycleActivity { @Override protected void

    onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... getLifecycle().addObserver(new FooObserver()); } }
  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ͷϥΠϑαΠΫϧʹϩά Λ࢓ࠐΜͰ࣮ߦͯ͠ΈΔͱ…
  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); } }
  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; } } }
  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; } } }
  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 } }
  26. Deep dive into Lifecycles

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

  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ͳΫϥε
  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); } }
  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); } }
  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"; }
  32. 2. Lifecycle.Eventͷൃ৴͸ҰମͲ͔͜Βʁ

  33. AndroidManifest (packaged)ʹո͛͠ͳprovider͕… <manifest ...> <application ...> ... <provider android:name="android.arch.lifecycle.LifecycleRuntimeTroja nProvider"

    android:exported="false" android:multiprocess="true" android:authorities="com.ogaclejapan.samples.lifecycle- trojan" /> </application> </manifest> (*´ŋωŋ`)̾̌˓( ͤΊͯެࣜυΩϡϝϯτʹॻ͍ͯ͘ΕΑ͒͒ɻɻɻ)
  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
  35. LifecycleDispatcherΫϥεͰ΍͍ͬͯΔ͜ͱʢͬ͘͟Γʣ • initॲཧͰActivityLifecycleCallbacks΁ίʔϧόοΫొ࿥ • onActivityCreatedͰ”ReportFragment”ͷ௥Ճͱ FragmentLifecycleCallbacks΁ίʔϧόοΫొ࿥ • onFragmentCreatedͰFragment͕ LifecycleRegistryOwnerΛ࣮૷͍ͯ͠Ε ͹”DestructionReportFragment”Λ௥Ճ

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

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

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

    • ֤LifecycleCallbacks಺ͰLifecycleRegistryOwnerΛ࣮૷ ͍ͯ͠Ε͹LifecycleRegistryʹରͯ͠”markState()” ͱ”handleLifecycleEvent()”ͷߋ৽ΛҰ෦୲͏
  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಺Ͱݺ͹Ε͍ͯΔ
  40. ͏ʔΜɺ૝૾Ҏ্ʹཪͰ৭ʑ΍ͬͯͨɻɻ

  41. LiveData<T>

  42. LiveDataΫϥε • ஋ͷߋ৽Λ҆શʹObserver΁௨஌Մೳ
 -> LifecycleOwnerͷState͕STARTED or RESUMED࣌ͷΈ௨஌ • Lifecycle-aware components.

    
 -> LifecycleOwnerͷState͕DESTROYED࣌͸observerΛࣗಈղআ public abstract class LiveData<T> { @MainThread public void observe(LifecycleOwner owner, Observer<T> observer) { ... } protected void postValue(T value) { ... } @MainThread protected void setValue(T value) { ... } public T getValue() { ... } ... }
  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͕ಉ͡ͳͷͰ௨஌͠ͳ͍
  44. MutableLiveDataΫϥε public class MutableLiveData<T> extends LiveData<T> { @Override public void

    postValue(T value) { super.postValue(value); } @Override public void setValue(T value) { super.setValue(value); } } • postValue() / setValue()Λpublicείʔϓ΁มߋ
 -> ObservableField΍BehaviorSubjectΈ͍ͨͳ஋ͷมߋݕ஌͕Ͱ ͖ΔϓϩύςΟͱͯ͠࢖͑ͦ͏
  45. TimerLiveDataΫϥε (Custom) public class TimerLiveData extends LiveData<Long> { 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); } }
  46. TimerLiveDataΫϥε (Custom) public class TimerLiveData extends LiveData<Long> { 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); } }
  47. LiveData<String> 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ͷΈ)
  48. ViewModel

  49. ViewModelΫϥε public abstract class ViewModel { protected void onCleared() {

    } } ViewModelProviders.of(activity) .get(FooViewModel.class) ViewModelStores.of(activity) HolderFragmentੜ੒
 -> setRetainInstance(true)
  50. https://speakerdeck.com/ogaclejapan/how-to-keep-data-between-orientation-changes

  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 extends Application> T getApplication() { return (T) mApplication; } }
  52. Architecture componentsͰਪ঑͞ΕΔΞʔΩςΫνϟ https://developer.android.com/topic/libraries/architecture/guide.html#the_final_architecture

  53. ࢀߟࢿྉ

  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
  55. ࠓޙʹظ଴ʂʂ