揽月老爸 發表於 2019-9-18 18:13:00

Android开发 LiveData与MutableLiveData详解

<h1><span style="color: rgba(0, 128, 128, 1)">版权声明</span></h1>
<p>本文来自博客园,作者:观心静&nbsp;,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11544273.html</p>
<div>本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。</div>
<h1><span style="color: rgba(0, 128, 128, 1)">前言</span></h1>
<p>  LiveData与ViewMode是经常搭配在一起使用的,但是为了不太混乱,我还是拆分开来说明,此篇博客只讲解 LiveData 与&nbsp;MutableLiveData的概念与使用方式(但是会涉及到ViewMode的部分代码).</p>
<p>  转载请注明来源:https://www.cnblogs.com/guanxinjing/p/11544273.html</p>
<h1><span style="color: rgba(0, 128, 128, 1)">LiveData是干什么的?</span></h1>
<p><span style="color: rgba(0, 128, 128, 1)">  <span style="color: rgba(0, 0, 0, 1)">由于LiveData和MutableLiveData都是一个概念的东西(只是作用范围不同)所以就不重复解释了,直接理解LiveData就可以明白MutableLiveData</span></span></p>
<p>  直接理解LiveData的字面意思是前台数据,其实这其实是很准确的表达.下面我们来说说LiveData的几个特征:</p>
<p>1.首先LiveData其实与数据实体类(POJO类)是一样的东西,它负责暂存数据.</p>
<p>2.其次LiveData其实也是一个观察者模式的数据实体类,它可以跟它注册的观察者回调数据是否已经更新.</p>
<p>3.LiveData还能知晓它绑定的Activity或者Fragment的生命周期,它只会给前台活动的activity回调(这个很厉害).这样你可以放心的在它的回调方法里直接将数据添加到View,而不用担心会不会报错.(你也可以不用费心费力判断Fragment是否还存活)</p>
<h1><span style="color: rgba(0, 128, 128, 1)">LiveData与MutableLiveData区别</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">LiveData与MutableLiveData的其实在概念上是一模一样的.唯一几个的区别如下:</span></p>
<p>1.<span style="color: rgba(0, 0, 0, 1)">MutableLiveData的父类是LiveData</span></p>
<p><span style="color: rgba(0, 0, 0, 1)">2.LiveData在实体类里可以通知指定某个字段的数据更新.</span></p>
<p><span style="color: rgba(0, 0, 0, 1)">3.<span style="color: rgba(0, 0, 0, 1)">MutableLiveData则是完全是整个实体类或者数据类型变化后才通知.不会细节到某个字段</span></span></p>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">4.LiveData不可变,MutableLiveData是可变的 -- 这个可能会让人有点误解,在博客最下面会解释.</span></span></p>
<p>&nbsp;</p>
<h1><span style="color: rgba(0, 128, 128, 1)">LiveData简单使用Demo</span></h1>
<h2><span style="color: rgba(0, 0, 0, 1)">创建LiveData</span></h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> DemoData <span style="color: rgba(0, 0, 255, 1)">extends</span> LiveData&lt;DemoData&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> tag1;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> tag2;
   
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getTag1() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> tag1;

    }
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setTag1(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> tag1) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.tag1 =<span style="color: rgba(0, 0, 0, 1)"> tag1;
      postValue(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> getTag2() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> tag2;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span> setTag2(<span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> tag2) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span>.tag2 =<span style="color: rgba(0, 0, 0, 1)"> tag2;
      postValue(</span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">);
    }
}</span></pre>
</div>
<p>很简单,只要继承LiveData并且在泛型里写下你的实体类,<strong>唯一需要注意的,<span style="color: rgba(0, 0, 0, 1)">postValue(<span style="color: rgba(0, 0, 255, 1)">this<span style="color: rgba(0, 0, 0, 1)">);</span></span></span></strong>这个方法是用于回调数据更新的方法. 你可以在你需要被观察的数据里添加.</p>
<h2>创建<span style="color: rgba(0, 0, 0, 1)">ViewModel</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">我们需要在<span style="color: rgba(0, 0, 0, 1)">ViewModel</span>实例化DemoData这个类. <span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">ViewModel<span style="color: rgba(0, 0, 0, 1)">(这个会在另一篇博客介绍)</span></span></span>这个是用于管理多个Activity或者Fragment数据的类。ViewModel是MVVM的概念。你可以百度一下,google提供这套东西就是为了MVVM。</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> DemoViewModel <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> ViewModel {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: Implement the ViewModel</span>
    <span style="color: rgba(0, 0, 255, 1)">private</span> DemoData mDemoData = <span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> DemoData();

    </span><span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> DemoData getDemoData() {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> mDemoData;
    }
}</span></pre>
</div>
<h2>在Activity或者<span style="color: rgba(0, 0, 0, 1)">Fragment</span>绑定</h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> Demo2Activity <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> AppCompatActivity {
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String TAG = "Demo2Activity"<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Button mBtnAddData;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> DemoViewModel mDemoViewModel;

    @Override
    </span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(Bundle savedInstanceState) {
      </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCreate(savedInstanceState);
      setContentView(R.layout.activity_demo2);
      mBtnAddData </span>=<span style="color: rgba(0, 0, 0, 1)"> findViewById(R.id.btn_add_data);
      mDemoViewModel </span>= ViewModelProviders.of(<span style="color: rgba(0, 0, 255, 1)">this</span>).get(DemoViewModel.<span style="color: rgba(0, 0, 255, 1)">class</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取ViewModel,让ViewModel与此activity绑定</span>
      mDemoViewModel.getDemoData().observe(<span style="color: rgba(0, 0, 255, 1)">this</span>, <span style="color: rgba(0, 0, 255, 1)">new</span> Observer&lt;DemoData&gt;() { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册观察者,观察数据的变化</span>
<span style="color: rgba(0, 0, 0, 1)">            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onChanged(DemoData demoData) {
                Log.e(TAG, </span>"onChanged: 数据有更新"<span style="color: rgba(0, 0, 0, 1)">);
            }
      });
      
      mBtnAddData.setOnClickListener(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> View.OnClickListener() {
            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onClick(View v) {
                Log.e(TAG, </span>"onClick: 已经点击"<span style="color: rgba(0, 0, 0, 1)">);
                mDemoViewModel.getDemoData().setTag1(</span>123); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">这里手动用按键点击更新数据</span>
<span style="color: rgba(0, 0, 0, 1)">
            }
      });
    }
}</span></pre>
</div>
<p>当我们点击按键后就会有数据更新后的回调触发:</p>
<div class="cnblogs_code">
<pre>2019-09-18 19:45:53.821 6649-6649/demo.yt.com.demo E/<span style="color: rgba(0, 0, 0, 1)">Demo2Activity: onClick: 已经点击
</span>2019-09-18 19:45:53.824 6649-6649/demo.yt.com.demo E/Demo2Activity: onChanged: 数据有更新</pre>
</div>
<p><strong>前面提过了,但是这里还是需要重新提一下! 注意! 这个数据只给前台的活动回调.</strong></p>
<p>&nbsp;</p>
<h1><span style="color: rgba(0, 128, 128, 1)">MutableLiveData简单使用Demo</span></h1>
<p>  &nbsp;前面已经解释了,所以我们这边直接看代码</p>
<h2><span style="color: rgba(0, 0, 0, 1)">创建MutableLiveData</span></h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> DemoViewModel <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> ViewModel {
    </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> TODO: Implement the ViewModel</span>
    <span style="color: rgba(0, 0, 255, 1)">private</span> MutableLiveData&lt;String&gt; myString = <span style="color: rgba(0, 0, 255, 1)">new</span> MutableLiveData&lt;&gt;<span style="color: rgba(0, 0, 0, 1)">();

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> MutableLiveData&lt;String&gt;<span style="color: rgba(0, 0, 0, 1)"> getMyString(){
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> myString;
    }

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setMyString(String string) {
      </span><span style="color: rgba(0, 0, 255, 1)">this</span><span style="color: rgba(0, 0, 0, 1)">.myString.setValue(string);
    }
}</span></pre>
</div>
<p><span style="color: rgba(0, 0, 0, 1)">因为MutableLiveData只是作用于变量所以我们直接就可以在ViewModel里实例化它,并且在泛型里标注变量的类型.</span></p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> MutableLiveData&lt;T&gt; <span style="color: rgba(0, 0, 255, 1)">extends</span> LiveData&lt;T&gt;<span style="color: rgba(0, 0, 0, 1)"> {
    @Override
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> postValue(T value) {
      </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.postValue(value);
    }

    @Override
    </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> setValue(T value) {
      </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.setValue(value);
    }
}</span></pre>
</div>
<p>&nbsp;</p>
<h2>在Activity或者<span style="color: rgba(0, 0, 0, 1)">Fragment绑定</span></h2>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> Demo1Activity <span style="color: rgba(0, 0, 255, 1)">extends</span><span style="color: rgba(0, 0, 0, 1)"> AppCompatActivity {
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">final</span> String TAG = "Demo1Activity"<span style="color: rgba(0, 0, 0, 1)">;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> DemoViewModel mDemoViewModel;
    </span><span style="color: rgba(0, 0, 255, 1)">private</span><span style="color: rgba(0, 0, 0, 1)"> Button mBtn1;

    @Override
    </span><span style="color: rgba(0, 0, 255, 1)">protected</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onCreate(Bundle savedInstanceState) {
      </span><span style="color: rgba(0, 0, 255, 1)">super</span><span style="color: rgba(0, 0, 0, 1)">.onCreate(savedInstanceState);
      setContentView(R.layout.activity_demo);
      mBtn1 </span>=<span style="color: rgba(0, 0, 0, 1)"> findViewById(R.id.btn_1);
      mDemoViewModel </span>= ViewModelProviders.of(<span style="color: rgba(0, 0, 255, 1)">this</span>).get(DemoViewModel.<span style="color: rgba(0, 0, 255, 1)">class</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">获取ViewModel,让ViewModel与此activity绑定</span>
      mDemoViewModel.getMyString().observe(<span style="color: rgba(0, 0, 255, 1)">this</span>, <span style="color: rgba(0, 0, 255, 1)">new</span> Observer&lt;String&gt;() { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册观察者</span>
<span style="color: rgba(0, 0, 0, 1)">            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onChanged(String s) {
                Log.e(TAG, </span>"onChanged: 值有变化="+<span style="color: rgba(0, 0, 0, 1)">s);
            }
      });

      mBtn1.setOnClickListener(</span><span style="color: rgba(0, 0, 255, 1)">new</span><span style="color: rgba(0, 0, 0, 1)"> View.OnClickListener() {
            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onClick(View v) {
                mDemoViewModel.setMyString(</span>"测试"); <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">用手动按键点击改变值</span>
<span style="color: rgba(0, 0, 0, 1)">

            }
      });
    }
}</span></pre>
</div>
<p>&nbsp;结果:</p>
<div class="cnblogs_code">
<pre>2019-09-18 19:59:38.294 6961-6961/demo.yt.com.demo E/Demo1Activity: onChanged: 值有变化=测试</pre>
</div>
<h1><span style="color: rgba(0, 128, 128, 1)">API全解</span></h1>
<h2><span style="color: rgba(51, 102, 255, 1)">postValue()</span></h2>
<p>  可能你已经在上面看到几次调用此方法了。postValue的特性如下:</p>
<p>  1.此方法可以在<strong>其他线程</strong>中调用</p>
<p>  2.如果在主线程执行发布的任务之前多次调用此方法,则仅将分配最后一个值。</p>
<p>  3.<span style="color: rgba(0, 0, 0, 1)">如果同时调用 .postValue(“a”)和.setValue(“b”),一定是值b被值a覆盖。</span></p>
<h2><span style="color: rgba(51, 102, 255, 1)">setValue()</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  setValue()的特性如下:<br></span></p>
<p><span style="color: rgba(0, 0, 0, 1)">  1.此方法<strong>只能在主线程</strong>里调用</span></p>
<h2><span style="color: rgba(51, 102, 255, 1)">getValue()</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 255, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(0, 0, 0, 1)">  返回当前值。 注意,在后台线程上调用此方法并不能保证将接收到最新的值。 <br></span></span></span></span></span></span></span></span></span></span></span></span></p>
<h2><span style="color: rgba(51, 102, 255, 1)">removeObserver(@NonNull <span style="font-weight: bold">final Observer&lt;? <span style="font-weight: bold">super T&gt; observer)&nbsp;</span></span></span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  移除指定的观察者</span></p>
<p><span style="color: rgba(51, 102, 255, 1)">例子:</span></p>
<div class="cnblogs_code">
<pre>      Observer&lt;String&gt; observer = <span style="color: rgba(0, 0, 255, 1)">new</span> Observer&lt;String&gt;<span style="color: rgba(0, 0, 0, 1)">() {
            @Override
            </span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> onChanged(String s) {
                mText.setText(</span>"内容改变=" +<span style="color: rgba(0, 0, 0, 1)"> s);
            }
      };
      mMainViewModel.getContent().observe(</span><span style="color: rgba(0, 0, 255, 1)">this</span>, observer);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">绑定</span>
      mMainViewModel.getContent().removeObserver(observer);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">解除</span></pre>
</div>
<h2><span style="color: rgba(51, 102, 255, 1)">removeObservers(@NonNull <span style="font-weight: bold">final LifecycleOwner owner)</span></span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  移除当前Activity或者Fragment的全部观察者</span></p>
<div class="cnblogs_code">
<pre>mMainViewModel.getContent().removeObservers(<span style="color: rgba(0, 0, 255, 1)">this</span>);</pre>
</div>
<h2><span style="color: rgba(51, 102, 255, 1)">&nbsp;hasActiveObservers()</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  如果此<span style="font-family: &quot;DejaVu Sans Mono&quot;">LiveData具有活动(Activity或者Fragment<span style="color: rgba(0, 0, 0, 1)"><span style="font-family: &quot;DejaVu Sans Mono&quot;">在前台</span></span>,当前屏幕显示)的观察者,则返回<span style="font-family: &quot;DejaVu Sans Mono&quot;">true。其实如果这个数据的观察者在最前台就返回true,否则false。</span></span></span></p>
<h2><span style="color: rgba(51, 102, 255, 1)">hasObservers()</span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  如果此LiveData具有观察者,则返回true。</span></p>
<p>&nbsp;</p>
<h2><span style="color: rgba(51, 102, 255, 1)">observe(@NonNull LifecycleOwner owner, @NonNull Observer&lt;? <span style="font-weight: bold">super T&gt; observer)</span></span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  设置此<span style="color: rgba(0, 0, 0, 1)">LiveData</span>数据当前activity或者Fragment的观察者,会给此activity或者Fragment在前台时回调数据。</span></p>
<p>&nbsp;</p>
<h2><span style="color: rgba(51, 102, 255, 1)"><span style="font-weight: bold">observeForever(@NonNull Observer&lt;? <span style="font-weight: bold">super T&gt; observer)</span></span></span></h2>
<p><span style="color: rgba(0, 0, 0, 1)">  1.设置永远观察者,永远不会被自动删除。您需要手动调用removeObserver(Observer)以停止观察此LiveData,</span></p>
<p><span style="color: rgba(0, 0, 0, 1)">  2.设置后此LiveData,一直处于活动状态,不管是否在前台哪里都会获得回调。</span></p>
<p>&nbsp;</p>
<h1 class="_1RuRku"><span style="color: rgba(0, 128, 128, 1)">MutableLiveData与LiveData区别:可变与不可变</span></h1>
<p><span style="color: rgba(0, 0, 0, 1)">初步学习后,很多人容易误解所谓的LiveData可变与MutableLiveData不可变</span>, 认为LiveData不是也可以set与post数据嘛? 怎么就不可变了</p>
<p>其实关键是LiveData是抽象类它的setValue与postValue 方法都是protected关键字, 而MutableLiveData是继承LiveData后将setValue与postValue都public了. 这里的可变与不可变是对外部调用时的情况,LiveData对外隐藏了setValue与postValue.</p>
<p>这里又引申了一个android官方实现MutableLiveData模版代码,让MutableLiveData的setValue与postValue不暴露出去,代码如下:</p>
<p>kotlin写法:</p>
<div class="cnblogs_code">
<pre>    val name: LiveData&lt;NameBean&gt; get() =<span style="color: rgba(0, 0, 0, 1)"> _name
    </span><span style="color: rgba(0, 0, 255, 1)">private</span> val _name = MutableLiveData&lt;NameBean&gt;()</pre>
</div>
<p>java写法:</p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(0, 0, 255, 1)">private</span> MutableLiveData&lt;NameBean&gt; name = <span style="color: rgba(0, 0, 255, 1)">new</span> MutableLiveData&lt;&gt;<span style="color: rgba(0, 0, 0, 1)">();

    </span><span style="color: rgba(0, 0, 255, 1)">public</span> LiveData&lt;NameBean&gt;<span style="color: rgba(0, 0, 0, 1)"> getName(){
      </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> name;
    }</span></pre>
</div>
<p>在外部调用时可以看到的情况,只有getValue()方法暴露</p>
<p><img src="https://img2020.cnblogs.com/blog/1497956/202111/1497956-20211126150437938-1725193363.png" alt=""></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><span style="color: rgba(0, 128, 128, 1)">END</span></p>

</div>
<div id="MySignature" role="contentinfo">
    <div style="text-align: center">
    <p style="color:orange;font-size:16px;" >本文来自博客园,作者:观心静 ,转载请注明原文链接:https://www.cnblogs.com/guanxinjing/p/11544273.html </p>
    <div style="color:orange;font-size:16px;">本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。 </div>
</div><br><br>
来源:https://www.cnblogs.com/guanxinjing/p/11544273.html
頁: [1]
查看完整版本: Android开发 LiveData与MutableLiveData详解