我是靠谱客的博主 动听西装,这篇文章主要介绍JetPack 之 LiveData 使用及源码分析,现在分享给大家,希望可以做个参考。

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
74
public 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
9
    public 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
17
    void 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
20
    void 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
11
    void 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
5
    private 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
26
    private 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
11
    private 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内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(60)

评论列表共有 0 条评论

立即
投稿
返回
顶部