LiveData 是在 Lifecycle 的基础上发展起来的,我们看看例子可以知道,需要借助于 ViewModel,我们来看个例子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74public class LDActivity extends AppCompatActivity implements View.OnClickListener{ private final static String TAG = "LDActivity"; private NameViewModel model; TextView nameTextView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_ld); nameTextView = findViewById(R.id.tv_user_name); model = new ViewModelProvider(this).get(NameViewModel.class); // model = ViewModelProviders.of(this).get(NameViewModel.class); Observer<String> nameObserver = new Observer<String>() { @Override public void onChanged(@Nullable final String newName) { nameTextView.setText(newName); } }; model.getCurrentName().observe(this, nameObserver); nameTextView.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()){ case R.id.tv_user_name: model.getCurrentName().setValue("death_pohuai"); break; } } } xml: activity_ld <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/tv_user_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="10dp" android:textSize="20dp" android:text="2356" tools:ignore="MissingConstraints" /> </androidx.constraintlayout.widget.ConstraintLayout> public class NameViewModel extends ViewModel { private MutableLiveData<String> currentName; public MutableLiveData<String> getCurrentName() { if (currentName == null) { currentName = new MutableLiveData<>(); } return currentName; } }
运行后,点击文本,发现文本的值变了。它是怎么实现的呢,说白了还是观察者模式,为什么说 LiveData 能有效避免内存泄漏呢?我们就来读读代码。
ViewModelProviders 这个类中的方法被标注为过时,但我们点进去后,发现其实还是 new 了一个 ViewModelProvider 对象,和我们上面写的一样,AppCompatActivity 继承了 ComponentActivity ,ComponentActivity 则实现了 ViewModelStoreOwner 这个接口,核心就一行代码
1
2
3
4
5
6
7
8@Override public ViewModelStore getViewModelStore() { ... if (mViewModelStore == null) { mViewModelStore = new ViewModelStore(); } return mViewModelStore; }
ViewModelStore 类的逻辑也很简单,里面就是有个成员变量 HashMap<String, ViewModel>,用来储存 ViewModel。 ComponentActivity 也实现了 HasDefaultViewModelProviderFactory 接口,核心也是就一行代码
1
2
3
4
5
6@Override public ViewModelProvider.Factory getDefaultViewModelProviderFactory() { ... mDefaultFactory = new SavedStateViewModelFactory(getApplication(), this,getIntent() != null ? getIntent().getExtras() : null); return mDefaultFactory; }
SavedStateViewModelFactory 中的逻辑稍微多点,看名字就知道它是工厂模式,构造方法最终会执行
1
2
3
4
5
6
7
8
9public SavedStateViewModelFactory(@NonNull Application application, @NonNull SavedStateRegistryOwner owner, @Nullable Bundle defaultArgs) { mSavedStateRegistry = owner.getSavedStateRegistry(); mLifecycle = owner.getLifecycle(); mDefaultArgs = defaultArgs; mApplication = application; mFactory = ViewModelProvider.AndroidViewModelFactory.getInstance(application); }
这条线先看到这,记住 SavedStateViewModelFactory 构造方法中有个 mFactory, 我们继续看 ViewModelProvider 的 get() 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21@MainThread public <T extends ViewModel> T get(@NonNull Class<T> modelClass) { String canonicalName = modelClass.getCanonicalName(); if (canonicalName == null) { throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels"); } return get(DEFAULT_KEY + ":" + canonicalName, modelClass); } @MainThread public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) { ViewModel viewModel = mViewModelStore.get(key); ... if (mFactory instanceof KeyedFactory) { viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass); } else { viewModel = (mFactory).create(modelClass); } mViewModelStore.put(key, viewModel); return (T) viewModel; }
这是简化后的代码,mViewModelStore 是 ViewModelStore 类型,用来存储变量值,第一次进来获取的 viewModel 为null;mFactory 则为 SavedStateViewModelFactory,它是继承了 KeyedFactory 类,所以看看 create(key, modelClass) 这个方法, key 是个字符串类型,modelClass 是 class 类型
1
2
3
4
5
6
7
8@Override public <T extends ViewModel> T create(@NonNull String key, @NonNull Class<T> modelClass) { ... if (constructor == null) { return mFactory.create(modelClass); } ... }
最终会执行到这,这里的 mFactory 是 ViewModelProvider 中的 内部类 AndroidViewModelFactory,又重新绕回 ViewModelProvider 类了,我们看看
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { if (AndroidViewModel.class.isAssignableFrom(modelClass)) { try { return modelClass.getConstructor(Application.class).newInstance(mApplication); } catch (NoSuchMethodException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (IllegalAccessException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InstantiationException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (InvocationTargetException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } } return super.create(modelClass); }
注意了,这里面是反射,选用了一个带 Application 参数的构造方法,如果抛出异常了,则会执行 super() 方法;AndroidViewModelFactory 的基类是 NewInstanceFactory,我们看看它的方法
1
2
3
4
5
6
7
8
9
10@Override public <T extends ViewModel> T create(@NonNull Class<T> modelClass) { try { return modelClass.newInstance(); } catch (InstantiationException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } catch (IllegalAccessException e) { throw new RuntimeException("Cannot create an instance of " + modelClass, e); } }
也是反射,是无参构造,获取到 viewModel 后,把它添加到 mViewModelStore 的 map 集合中。从这里我们可以看出,NameViewModel 继承 ViewModel 并且需要保证一个默认的无参构造,类型是 public ,也就是默认即可。 上文中是 LDActivity 中创建了 NameViewModel 类型的对象,如果在 LDActivity1 或 LDActivity2 中也用这个方法,那么得到的 NameViewModel 对象是同一个,因为 mViewModelStore 的 map 有缓存作用,这样我们可以实现数据共享, NameViewModel 就像是一个伪单利一样的存在。
MutableLiveData 继承于 LiveData,MutableLiveData 中的代码比较少,只是起到一个过渡的作用,主要逻辑还是在 LiveData 中,observe() 是添加监听的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18@MainThread public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) { assertMainThread("observe"); if (owner.getLifecycle().getCurrentState() == DESTROYED) { return; } LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); ... owner.getLifecycle().addObserver(wrapper); } static void assertMainThread(String methodName) { if (!ArchTaskExecutor.getInstance().isMainThread()) { throw new IllegalStateException("Cannot invoke " + methodName + " on a background" + " thread"); } }
先检查当前线程是否是 UI 线程,最终还是 DefaultTaskExecutor 类在做检查,它里面有线程池和 Handler,感兴趣的可以看看;LifecycleOwner 则是上一章说的东西,在这里用来检查生命周期,如果 Activity 已经走过 onDestroy() 后,此方法就到此为止,不会继续往下执行了。 LifecycleBoundObserver 实现了 LifecycleEventObserver 接口,然后 wrapper 也被添加到 Lifecycle 的生命周期监听中了,此时随着 Activity 的生命周期执行, LifecycleBoundObserver 中也会接受到回调,看看
1
2
3
4
5
6
7
8
9
10
11
12
13
14@Override public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) { if (mOwner.getLifecycle().getCurrentState() == DESTROYED) { removeObserver(mObserver); return; } activeStateChanged(shouldBeActive()); } @Override boolean shouldBeActive() { return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); }
这个方法中,也有个判断,如果 Lifecycle 的 state 状态为 DESTROYED ,则移除 mObserver 监听,这样就保证了后续即使再有数据变化,mObserver 也不会执行了,这样就避免了不必要的内存泄漏和空指针等问题。shouldBeActive() 中判断是否存活,这里是判断 Lifecycle 的状态是否大于或等于 STARTED,我们看看 activeStateChanged() 方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17void activeStateChanged(boolean newActive) { if (newActive == mActive) { return; } mActive = newActive; boolean wasInactive = LiveData.this.mActiveCount == 0; LiveData.this.mActiveCount += mActive ? 1 : -1; if (wasInactive && mActive) { onActive(); } if (LiveData.this.mActiveCount == 0 && !mActive) { onInactive(); } if (mActive) { dispatchingValue(this); } }
这个方法代码比较有意思, newActive 值相同的话,只会执行一次;刚开始 mActive 为 false,如果 newActive 为 true,则 mActiveCount 初始值为0,wasInactive 为 true,此时会执行 onActive() 方法,如果下一次调用该方法, newActive 还是true,则直接 return; newActive 为 false 时,mActiveCount 值在+1和-1后,会重新恢复为0,此时会执行 onInactive() 方法。 也就是说这两个方法是成对出现的,这两个方法其实对应的就是 Activity 的 onStart() 和 onStop() 方法,我们在自定义 LiveData 时,可以重写这两个方法,做些自己逻辑的操作。 最后看看 dispatchingValue(this) 方法,这个是只有 mActive 为 true 的时候才会调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20void dispatchingValue(@Nullable ObserverWrapper initiator) { ... considerNotify(initiator); ... } private void considerNotify(ObserverWrapper observer) { if (!observer.mActive) { return; } if (!observer.shouldBeActive()) { observer.activeStateChanged(false); return; } if (observer.mLastVersion >= mVersion) { return; } observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData); }
这是简化后的代码,在 considerNotify() 方法中,此时 mVersion 为0,observer.mLastVersion 值为 -1,所以此时这个方法也就 return 了。 LiveData 的 observe() 方法分析就先到这里了,我们看看 setValue() 和 postValue() 方法,看代码后会发现,setValue() 必须在 UI 线程中调用, postValue() 则是会通过 Handler 切换线程到 UI 线程,然后调用 setValue() 方法,
1
2
3
4
5
6
7@MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }
又是 dispatchingValue(null) 方法,此时由于参数为 null, 则 dispatchingValue() 可简化为
1
2
3
4
5
6
7
8
9
10
11void dispatchingValue(@Nullable ObserverWrapper initiator) { ... for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator = mObservers.iteratorWithAdditions(); iterator.hasNext(); ) { considerNotify(iterator.next().getValue()); if (mDispatchInvalidated) { break; } } ... }
在 observe() 方法中,mObservers 添加了 LifecycleBoundObserver,在这个方法中,遍历了它,取出了添加到 mObservers 中的 LifecycleBoundObserver 对象,然后调用了 considerNotify() 方法,可简化为
1
2
3
4
5private void considerNotify(ObserverWrapper observer) { ... observer.mLastVersion = mVersion; observer.mObserver.onChanged((T) mData); }
observer.mObserver 就是我们 LDActivity 中的 nameObserver,此时调用了 onChanged() 方法,此时 mData 即为 setValue("death_pohuai") 方法中的 "death_pohuai", nameObserver 的实现方法中: nameTextView.setText(newName) ,这就是我们看到的现象。
MediatorLiveData 是 MutableLiveData 的子类,它提供了 addSource(LiveData<S> source, Observer<? super S> onChanged) 方法,意思是如果 source 这个对象里面有值变化,onChanged 马上就会执行回调,它是怎么实现的呢?看看这个方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@MainThread public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged) { Source<S> e = new Source<>(source, onChanged); Source<?> existing = mSources.putIfAbsent(source, e); if (existing != null && existing.mObserver != onChanged) { throw new IllegalArgumentException( "This source was already added with the different observer"); } if (existing != null) { return; } if (hasActiveObservers()) { e.plug(); } }
在这里,hasActiveObservers() 方法为false,我们只看 前两行代码就行了,创建了 Source 对象,然后添加到 mSources 集合中,看看 Source 这个类,实现了 Observer 接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26private static class Source<V> implements Observer<V> { final LiveData<V> mLiveData; final Observer<? super V> mObserver; int mVersion = START_VERSION; Source(LiveData<V> liveData, final Observer<? super V> observer) { mLiveData = liveData; mObserver = observer; } void plug() { mLiveData.observeForever(this); } void unplug() { mLiveData.removeObserver(this); } @Override public void onChanged(@Nullable V v) { if (mVersion != mLiveData.getVersion()) { mVersion = mLiveData.getVersion(); mObserver.onChanged(v); } } }
又是回调,并且 plug() 中 observeForever() 方法注册了回调,removeObserver() 移除了回调。 前面说了,LiveData 会随着Activity的生命周期执行 onActive() 和 onInactive() 方法,我们看看 MediatorLiveData 的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15@CallSuper @Override protected void onActive() { for (Map.Entry<LiveData<?>, Source<?>> source : mSources) { source.getValue().plug(); } } @CallSuper @Override protected void onInactive() { for (Map.Entry<LiveData<?>, Source<?>> source : mSources) { source.getValue().unplug(); } }
果然,从 mSources 中获取到 Source,然后调用了 plug() 和 unplug() 方法;调用 LiveData 对象的 setValue() 赋值时,就会触发 Source 的 onChanged()方法,然后回调 mObserver 的 onChanged() 方法。这样就实现了该功能,个人觉得这个功能有点鸡肋。细心的朋友会发现,plug() 方法中 LiveData 使用的是 observeForever()方法,那么它与 observe() 方法有什么区别呢?
1
2
3
4
5
6
7
8
9
10
11
12
13
14@MainThread public void observeForever(@NonNull Observer<? super T> observer) { assertMainThread("observeForever"); AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); if (existing instanceof LiveData.LifecycleBoundObserver) { throw new IllegalArgumentException("Cannot add the same observer" + " with different lifecycles"); } if (existing != null) { return; } wrapper.activeStateChanged(true); }
这里要注意,在此创建的是 AlwaysActiveObserver 对象,同时主动调用了 activeStateChanged(true) 方法,参数为 true,看看 AlwaysActiveObserver 类
1
2
3
4
5
6
7
8
9
10
11private class AlwaysActiveObserver extends ObserverWrapper { AlwaysActiveObserver(Observer<? super T> observer) { super(observer); } @Override boolean shouldBeActive() { return true; } }
AlwaysActiveObserver 仅仅是继承了 ObserverWrapper,没有实现 LifecycleEventObserver 接口,自然有不会接受 Activity 的生命周期变化的监听事件了;并且, shouldBeActive() 方法返回的值是固定的 true, 再加上 activeStateChanged(true) 方法,也就是说在调用 observeForever() 方法时,就已经执行了 activeStateChanged(true) 方法,此时会执行 onActive() 方法。 我们再看看 removeObserver() 方法
1
2
3
4
5
6
7
8
9
10@MainThread public void removeObserver(@NonNull final Observer<? super T> observer) { assertMainThread("removeObserver"); ObserverWrapper removed = mObservers.remove(observer); if (removed == null) { return; } removed.detachObserver(); removed.activeStateChanged(false); }
也会调用 activeStateChanged(false) 方法,值为 false, 此时会执行 onInactive() 方法。 其实说白了,整个就是个观察者模式的使用。
最后
以上就是动听西装最近收集整理的关于JetPack 之 LiveData 使用及源码分析的全部内容,更多相关JetPack内容请搜索靠谱客的其他文章。
发表评论 取消回复