[JetPack] LiveData源码解析

{"type":"doc","content":[{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"1. 背景 ","attrs":{}},{"type":"link","attrs":{"href":"https://developer.android.com/topic/libraries/architecture/livedata#observelivedataobjects","title":""},"content":[{"type":"text","text":"官网LiveData","attrs":{}}]}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"    笔者在开发一款即时通讯和音视频应用时,发现需要花费很大的力量去处理系统组件之间的数据传递,稍微有点不注意,就会出现状态错乱不同步的问题,影响用户体验,也给系统稳定性带来了许多挑战。因此,在我们2.0版本的重构过程中,毅然决定引入LiveData,经过实践证明,其是一种优秀的解决方案,很适合处理此类问题,但也有一些细节需要注意,因此有了这篇文章,希望可以记录下来。","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.1 定义","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据持有类","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"感知组件生命周期","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"数据能够被观察者所观察","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"1.2 使用 LiveData 的优势","attrs":{}}]},{"type":"bulletedlist","content":[{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"确保界面符合数据状态","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不会发生内存泄漏","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不会因 Activity 停止而导致崩溃","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"不再需要手动处理生命周期","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"数据始终保持最新状态","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"适当的配置更改","attrs":{}}]}],"attrs":{}},{"type":"listitem","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong","attrs":{}}],"text":"共享资源","attrs":{}}]}],"attrs":{}}],"attrs":{}},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"2. 正文","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.1 使用 LiveData 步骤","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.1.1 创建 LiveData 实例以存储某种类型的数据。这通常在 ViewModel 类中完成。","attrs":{}}]},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"     public class NameViewModel extends ViewModel {\n\n        // Create a LiveData with a String\n        private MutableLiveData currentName;\n\n        public MutableLiveData getCurrentName() {\n            if (currentName == null) {\n                currentName = new MutableLiveData();\n            }\n            return currentName;\n        }\n\n        // Rest of the ViewModel...\n    }","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.1.2 创建可定义 onChanged() 方法的 Observer 对象,该方法可以控制当 LiveData 对象存储的数据更改时会发生什么。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中创建 Observer 对象。使用 observe() 方法将 Observer 对象附加到 LiveData 对象。observe() 方法会采用 LifecycleOwner 对象。这样会使 Observer 对象订阅 LiveData 对象,以使其收到有关更改的通知。通常情况下,您可以在界面控制器(如 Activity 或 Fragment)中附加 Observer 对象","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"    public class NameActivity extends AppCompatActivity {\n\n        private NameViewModel model;\n\n        @Override\n        protected void onCreate(Bundle savedInstanceState) {\n            super.onCreate(savedInstanceState);\n\n            // Other code to setup the activity...\n\n            // Get the ViewModel.\n            model = new ViewModelProvider(this).get(NameViewModel.class);\n\n            // Create the observer which updates the UI.\n            final Observer nameObserver = new Observer() {\n                @Override\n                public void onChanged(@Nullable final String newName) {\n                    // Update the UI, in this case, a TextView.\n                    nameTextView.setText(newName);\n                }\n            };\n\n            // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.\n            model.getCurrentName().observe(this, nameObserver);\n        }\n    }","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.1.3 更新 LiveData 对象,LiveData 没有公开可用的方法来更新存储的数据。MutableLiveData 类将公开 setValue(T) 和 postValue(T) 方法,如果您需要修改存储在 LiveData 对象中的值,则必须使用这些方法。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"    button.setOnClickListener(new OnClickListener() {\n        @Override\n        public void onClick(View v) {\n            String anotherName = \"John Doe\";\n            model.getCurrentName().setValue(anotherName);\n        }\n    });","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":3},"content":[{"type":"text","text":"2.2 LiveData 代码分析","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.2.1 MutableLiveData.java(LiveData的一个派生类,由于LiveData并未提供给外部更新数据的接口,所以一般使用MutableLiveData来实例化LiveData)","attrs":{}}]},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"package androidx.lifecycle;\n\n/**\n * {@link LiveData} which publicly exposes {@link #setValue(T)} and {@link #postValue(T)} method.\n *\n * @param The type of data hold by this instance\n */\n@SuppressWarnings(\"WeakerAccess\")\npublic class MutableLiveData extends LiveData {\n\n    /**\n     * Creates a MutableLiveData initialized with the given {@code value}.\n     *\n     * @param value initial value\n     */\n    public MutableLiveData(T value) {\n        super(value);\n    }\n\n    /**\n     * Creates a MutableLiveData with no value assigned to it.\n     */\n    public MutableLiveData() {\n        super();\n    }\n\n    @Override\n    public void postValue(T value) {\n        super.postValue(value);\n    }\n\n    @Override\n    public void setValue(T value) {\n        super.setValue(value);\n    }\n}","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.2.2 LiveData.observe()方法","attrs":{}}]},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"    @MainThread // 标记该方法只允许在主线程运行,一般是在Activity/Service的onCreate方法中执行\n     // 第一个参数 LifecycleOwner,表示的是一个具有生命周期的通用组件,如Activity/Service\n     // 第二个参数 Observer,就是我们的观察者实例,当数据变化时会执行onChange方法\n\n    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer super T> observer) {\n        assertMainThread(\"observe\"); // 主线程断言检测\n        if (owner.getLifecycle().getCurrentState() == DESTROYED) { // 如果当前组件的生命周期是销毁,则立即返回\n            // ignore\n            return;\n        }\n        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); // 一个用于关联 组件和观察者 之间的对象\n        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);\n        if (existing != null && !existing.isAttachedTo(owner)) { // 不允许同一个观察者观察不同的组件\n            throw new IllegalArgumentException(\"Cannot add the same observer\"\n                    + \" with different lifecycles\");\n        }\n        if (existing != null) {\n            return;\n        }\n        owner.getLifecycle().addObserver(wrapper); // 添加到组件的观察者队列\n    }","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":4},"content":[{"type":"text","text":"2.2.3 注意事项:","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"    我们看一段注释,如果你已经post一个任务给主线程,但还未来得及执行,此时你再多次调用postValue,则意味着最新的值会被post,后面的值会覆盖前面的值。这一点需要特别注意,笔者在开发的时候,由于在Service中根据网络状态来更新LiveData的值,但是发现Activity中部分值无法观察到,后来看了注释才焕然大悟。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"codeblock","attrs":{"lang":""},"content":[{"type":"text","text":"/**\n     * Posts a task to a main thread to set the given value. So if you have a following code\n     * executed in the main thread:\n     *
\n     * liveData.postValue(\"a\");\n     * liveData.setValue(\"b\");\n     * 
\n     * The value \"b\" would be set at first and later the main thread would override it with\n     * the value \"a\".\n     *

\n     * If you called this method multiple times before a main thread executed a posted task, only\n     * the last value would be dispatched.\n     *\n     * @param value The new value\n     */\n    protected void postValue(T value) {","attrs":{}}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"3. 总结","attrs":{}}]},{"type":"paragraph","attrs":{"indent":1,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本文简单介绍了JetPack组件中的一个话题,但不仅仅于此,未完待续,敬请期待。","attrs":{}}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}}]}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章