Share
Embed
Transcript
34 slides
-
ViewModel - Android Jetpack Components ͷ 1 ͭͷίϯϙʔωϯτ - ը໘ճసͷը໘ߏมߋΛ·͍ͨͩσʔλอ͕࣋Մೳ
- Activity ͷϥΠϑαΠΫϧΑΓ͘ੜ͖Δ 4 -
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 -
// Activity ͕ىಈͨ͠ onCreate - Activity :132818886 - ViewModel:249530701 onStart
onResume // Activity ͕ճసͨ͠ onPause onStop onRetainNonConfigurationInstance onDestroy onCreate - Activity :103312713 - ViewModel:249530701 <- ಉ͡ ViewModel Ͱ͋Δ͜ͱ͕Θ͔Δ onStart onResume 7 -
ͳ͢͜ͱ - ViewModelProvider - ViewModelStore - FragmentActivity implements ViewModelStoreOwner -
Activity - getLastNonConfigurationInstance() - onRetainNonConfigurationInstance() - ·ͱΊ 8 -
લఏ݅ 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 -
લఏ݅ 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 -
package androidx.lifecycle; public class ViewModelProvider { public interface Factory {
@NonNull <T extends ViewModel> T create(@NonNull Class<T> 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 -
package androidx.lifecycle; public class ViewModelProvider { private final ViewModelStore mViewModelStore;
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> 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 -
package androidx.lifecycle; public class ViewModelStore { private final HashMap<String, ViewModel>
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 -
package androidx.lifecycle; public class ViewModelProvider { private final ViewModelStore mViewModelStore;
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> 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 -
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 -
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 -
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 -
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 -
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<String, Object> children; FragmentManagerNonConfig fragments; ArrayMap<String, LoaderManager> loaders; VoiceInteractor voiceInteractor; } } 24 -
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 -
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 -
package android.app; public class Activity extends ContextThemeWrapper implements ... {
public Object onRetainNonConfigurationInstance() { return null; } ... } 28 -
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 -
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 -
·ͱΊ 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 -
·ͱΊ 1/3 ճసલ - FragmentActivity#onCreate() - ͜ͷ࣌Ͱ·ͩ FragmentActivity ͷ mViewModelStore
null - HogeActivity#onCreate() - ViewModelProvider ΠϯελϯεΛੜ͢Δ - ͜ͷ࣌Ͱɺ FragmentActivity#getViewModelStore() ͕ݺΕΔͨΊ FragmentActivity ͷ mViewModelStore ʹΠϯελϯε͕ೖ͞Ε͍ͯΔ - ViewModelProvider#get() ͔Β ViewModel ͷΠϯελϯεΛऔಘͰ͖Δ - ͜ͷ ViewModel ͷΠϯελϯεɺ FragmentActivity ͕࣋ͭ mViewModelStore ʹ֨ೲ͞Ε͍ͯΔ 32 -
·ͱΊ 2/3 ճస࣌ - FragmentActivity#onRetainNonConfigurationInsta nce() - NonConfigurationInstances ΫϥεͷΠϯελϯεΛ ฦ͍ͯ͠Δ
- FragmentActivity ͕࣋ͭ mViewModelStore ͕֨ೲ ͞Ε͍ͯΔ 33 -
·ͱΊ 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