Slide 1

Slide 1 text

ViewModel ͕ը໘ճసͯ͠΋อ࣋͞ΕΔ࢓૊Έ sho5nn @ Otemachi.apk #01 1

Slide 2

Slide 2 text

- @sho5nn - Android 6 ೥͙Β͍ - ϑϦʔϥϯε 2

Slide 3

Slide 3 text

ViewModel 3

Slide 4

Slide 4 text

ViewModel - Android Jetpack Components ͷ 1 ͭͷίϯϙʔωϯτ - ը໘ճస౳ͷը໘ߏ੒มߋΛ·͍ͨͩσʔλอ͕࣋Մೳ - Activity ͷϥΠϑαΠΫϧΑΓ௕͘ੜ͖Δ 4

Slide 5

Slide 5 text

https://developer.android.com/topic/libraries/architecture/viewmodel 5

Slide 6

Slide 6 text

class HogeActivity : AppCompatActivity { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Log.d(TAG, "onCreate") val activity: FragmentActivity = this val factory : ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory() val viewModel = ViewModelProvider(activity, factory).get(FooViewModel::class.java) Log.d(TAG, " - Activity :${this.hashCode()}") Log.d(TAG, " - ViewModel:${viewModel.hashCode()}") } } 6

Slide 7

Slide 7 text

// Activity ͕ىಈͨ͠ onCreate - Activity :132818886 - ViewModel:249530701 onStart onResume // Activity ͕ճసͨ͠ onPause onStop onRetainNonConfigurationInstance onDestroy onCreate - Activity :103312713 - ViewModel:249530701 <- ಉ͡ ViewModel Ͱ͋Δ͜ͱ͕Θ͔Δ onStart onResume 7

Slide 8

Slide 8 text

͸ͳ͢͜ͱ - ViewModelProvider - ViewModelStore - FragmentActivity implements ViewModelStoreOwner - Activity - getLastNonConfigurationInstance() - onRetainNonConfigurationInstance() - ·ͱΊ 8

Slide 9

Slide 9 text

લఏ৚݅ dependencies { implementation 'androidx.appcompat:appcompat:1.0.2' ... } +--- androidx.appcompat:appcompat:1.0.2 | +--- androidx.fragment:fragment:1.0.0 | | \--- androidx.lifecycle:lifecycle-viewmodel:2.0.0 (*) ... 9

Slide 10

Slide 10 text

લఏ৚݅ class HogeActivity : AppCompatActivity { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val activity: FragmentActivity = this val factory : ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory() val viewModel = ViewModelProvider(activity, factory).get(FooViewModel::class.java) } } ͜ͷίʔυΛ΋ͱʹɺ࢓૊ΈΛ௥͍͖ͬͯ·͢ɻ 10

Slide 11

Slide 11 text

ViewModelProvider 11

Slide 12

Slide 12 text

package androidx.lifecycle; public class ViewModelProvider { public interface Factory { @NonNull T create(@NonNull Class modelClass); } private final Factory mFactory; private final ViewModelStore mViewModelStore; public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) { this(owner.getViewModelStore(), factory); } public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) { mFactory = factory; this.mViewModelStore = store; } ... } 12

Slide 13

Slide 13 text

package androidx.lifecycle; public class ViewModelProvider { private final ViewModelStore mViewModelStore; public T get(@NonNull String key, @NonNull Class modelClass) { ViewModel viewModel = mViewModelStore.get(key); if (modelClass.isInstance(viewModel)) { //noinspection unchecked return (T) viewModel; } else { //noinspection StatementWithEmptyBody if (viewModel != null) { // TODO: log a warning. } } viewModel = mFactory.create(modelClass); mViewModelStore.put(key, viewModel); //noinspection unchecked return (T) viewModel; } ... } 13

Slide 14

Slide 14 text

ViewModelStore 14

Slide 15

Slide 15 text

package androidx.lifecycle; public class ViewModelStore { private final HashMap mMap = new HashMap<>(); final void put(String key, ViewModel viewModel) { ViewModel oldViewModel = mMap.put(key, viewModel); if (oldViewModel != null) { oldViewModel.onCleared(); } } final ViewModel get(String key) { return mMap.get(key); } public final void clear() { for (ViewModel vm : mMap.values()) { vm.onCleared(); } mMap.clear(); } } 15

Slide 16

Slide 16 text

package androidx.lifecycle; public class ViewModelProvider { private final ViewModelStore mViewModelStore; public T get(@NonNull String key, @NonNull Class modelClass) { ViewModel viewModel = mViewModelStore.get(key); if (modelClass.isInstance(viewModel)) { //noinspection unchecked return (T) viewModel; } else { //noinspection StatementWithEmptyBody if (viewModel != null) { // TODO: log a warning. } } viewModel = mFactory.create(modelClass); mViewModelStore.put(key, viewModel); //noinspection unchecked return (T) viewModel; } ... } 16

Slide 17

Slide 17 text

class HogeActivity : AppCompatActivity { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val activity: FragmentActivity = this val factory : ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory() val viewModel = ViewModelProvider(activity, factory).get(FooViewModel::class.java) } } 17

Slide 18

Slide 18 text

package androidx.lifecycle; public class ViewModelProvider { private final ViewModelStore mViewModelStore; public ViewModelProvider(@NonNull ViewModelStoreOwner owner, @NonNull Factory factory) { this(owner.getViewModelStore(), factory); } public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) { mFactory = factory; this.mViewModelStore = store; } } 18

Slide 19

Slide 19 text

package androidx.lifecycle; public interface ViewModelStoreOwner { @NonNull ViewModelStore getViewModelStore(); } 19

Slide 20

Slide 20 text

FragmentActivity implements ViewModelStoreOwner 20

Slide 21

Slide 21 text

package androidx.fragment.app; public class FragmentActivity extends ComponentActivity implements ViewModelStoreOwner ... { private ViewModelStore mViewModelStore; @NonNull @Override public ViewModelStore getViewModelStore() { ... if (mViewModelStore == null) { NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null) { // Restore the ViewModelStore from NonConfigurationInstances mViewModelStore = nc.viewModelStore; } if (mViewModelStore == null) { mViewModelStore = new ViewModelStore(); } } return mViewModelStore; } } 21

Slide 22

Slide 22 text

package androidx.fragment.app; public class FragmentActivity extends ComponentActivity implements ViewModelStoreOwner ... { private ViewModelStore mViewModelStore; @NonNull @Override public ViewModelStore getViewModelStore() { ... if (mViewModelStore == null) { NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); ... } } static final class NonConfigurationInstances { Object custom; ViewModelStore viewModelStore; FragmentManagerNonConfig fragments; } } 22

Slide 23

Slide 23 text

Activity#getLastNonConfigurationInstance() 23

Slide 24

Slide 24 text

package android.app; public class Activity extends ContextThemeWrapper implements ... { /* package */ NonConfigurationInstances mLastNonConfigurationInstances; @Nullable public Object getLastNonConfigurationInstance() { return mLastNonConfigurationInstances != null ? mLastNonConfigurationInstances.activity : null; } static final class NonConfigurationInstances { Object activity; HashMap children; FragmentManagerNonConfig fragments; ArrayMap loaders; VoiceInteractor voiceInteractor; } } 24

Slide 25

Slide 25 text

https://developer.android.com/reference/android/app/Activity.html#getLastNonConfigurationInstance() Retrieve the non-configuration instance data that was previously returned by onRetainNonConfigurationInstance(). This will be available from the initial onCreate(Bundle) and onStart() calls to the new instance, allowing you to extract any useful dynamic state from the previous instance. 25

Slide 26

Slide 26 text

Activity#onRetainNonConfigurationInstance() 26

Slide 27

Slide 27 text

https://developer.android.com/reference/android/app/Activity#onRetainNonConfigurationInstance() Called by the system, as part of destroying an activity due to a configuration change, when it is known that a new instance will immediately be created for the new configuration. You can return any object you like here, including the activity instance itself, which can later be retrieved by calling getLastNonConfigurationInstance() in the new activity instance. 27

Slide 28

Slide 28 text

package android.app; public class Activity extends ContextThemeWrapper implements ... { public Object onRetainNonConfigurationInstance() { return null; } ... } 28

Slide 29

Slide 29 text

package androidx.fragment.app; public class FragmentActivity extends ComponentActivity implements ViewModelStoreOwner, ... { private ViewModelStore mViewModelStore; @Override public final Object onRetainNonConfigurationInstance() { Object custom = onRetainCustomNonConfigurationInstance(); FragmentManagerNonConfig fragments = mFragments.retainNestedNonConfig(); if (fragments == null && mViewModelStore == null && custom == null) { return null; } NonConfigurationInstances nci = new NonConfigurationInstances(); nci.custom = custom; nci.viewModelStore = mViewModelStore; nci.fragments = fragments; return nci; } } 29

Slide 30

Slide 30 text

package androidx.fragment.app; public class FragmentActivity extends ComponentActivity implements ViewModelStoreOwner ... { private ViewModelStore mViewModelStore; @SuppressWarnings("deprecation") @Override protected void onCreate(@Nullable Bundle savedInstanceState) { mFragments.attachHost(null /*parent*/); super.onCreate(savedInstanceState); NonConfigurationInstances nc = (NonConfigurationInstances) getLastNonConfigurationInstance(); if (nc != null && nc.viewModelStore != null && mViewModelStore == null) { mViewModelStore = nc.viewModelStore; } ... } } 30

Slide 31

Slide 31 text

·ͱΊ class HogeActivity : AppCompatActivity { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val activity: FragmentActivity = this val factory : ViewModelProvider.Factory = ViewModelProvider.NewInstanceFactory() val viewModel = ViewModelProvider(activity, factory).get(FooViewModel::class.java) } } 31

Slide 32

Slide 32 text

·ͱΊ 1/3 ճసલ - FragmentActivity#onCreate() - ͜ͷ࣌఺Ͱ͸·ͩ FragmentActivity ͷ mViewModelStore ͸ null - HogeActivity#onCreate() - ViewModelProvider ΠϯελϯεΛੜ੒͢Δ - ͜ͷ࣌఺Ͱɺ FragmentActivity#getViewModelStore() ͕ݺ͹ΕΔͨΊ FragmentActivity ͷ mViewModelStore ʹΠϯελϯε͕୅ೖ͞Ε͍ͯΔ - ViewModelProvider#get() ͔Β ViewModel ͷΠϯελϯεΛऔಘͰ͖Δ - ͜ͷ ViewModel ͷΠϯελϯε͸ɺ FragmentActivity ͕࣋ͭ mViewModelStore ʹ֨ೲ͞Ε͍ͯΔ 32

Slide 33

Slide 33 text

·ͱΊ 2/3 ճస࣌ - FragmentActivity#onRetainNonConfigurationInsta nce() - NonConfigurationInstances ΫϥεͷΠϯελϯεΛ ฦ͍ͯ͠Δ - FragmentActivity ͕࣋ͭ mViewModelStore ͕֨ೲ ͞Ε͍ͯΔ 33

Slide 34

Slide 34 text

·ͱΊ 3/3 ճసޙ - FragmentActivity#onCreate() - Activity#getLastNonConfigurationInstance() ͔ΒɺNonConfigurationInstances ΫϥεͷΠϯελ ϯεΛऔಘ͍ͯ͠Δ - NonConfigurationInstances ΫϥεͷΠϯελϯεʹ֨ೲ͞Ε͍ͯΔɺճసલͷ FragmentActivity ͕ ͍࣋ͬͯͨ ViewModelStore Λɺ ճసޙͷ FragmentActivity ͸ࣗ਎ͷ ViewModelStore ʹ୅ೖͯ͠ ͍Δ - HogeActivity#onCreate() - ViewModelProvider ΠϯελϯεΛੜ੒͢Δ - ͜ͷ࣌఺Ͱɺ FragmentActivity ͸ɺճసલͷ ViewModelStore ΠϯελϯεΛ͍࣋ͬͯΔ - ViewModelProvider#get() ͔Β ViewModel ͷΠϯελϯεΛऔಘͰ͖Δ - ͜ͷ ViewModel ͸ɺ FragmentActivity ͕࣋ͭ ViewModelStore ʹ֨ೲ͞Ε͍ͯΔΠϯελϯεͰ͋ Γɺ͔ͭɺ ճసલʹੜ੒͞Ε͍ͯͨ ViewModel Ͱ͋Δ ! 34