我们应该使用lambda或匿名类来观察LiveData

时间:2018-04-01 12:18:43

标签: android android-architecture-components android-livedata

当我使用lambda和匿名类来观察LiveData

时,我意识到有一个显着的不同

匿名类

button.setOnClickListener(e -> {
    mainViewModel.getCounter().observe(MainFragment.this, new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer counter) {
            android.util.Log.i("CHEOK", "Observer 3 : " + counter + ", " + this);
        }
    });
});

的Lamda

button.setOnClickListener(e -> {
    mainViewModel.getCounter().observe(MainFragment.this, counter -> {
        android.util.Log.i("CHEOK", "Observer 3 : " + counter);
    });
});

当您多次单击该按钮时,对于匿名类,将创建多个不同的观察实例,并传递给LiveData。因此,如果您按下按钮3次,然后执行

counter.postValue(counter.getValue());

你会得到

Observer 3 : 123, com.xxx.MainFragment$1@cd023a
Observer 3 : 123, com.xxx.MainFragment$1@beb52e1
Observer 3 : 123, com.xxx.MainFragment$1@d1ffcf4

但是对于lamda,即使多次按下按钮,也只会创建一个Observer实例。你只会得到

Observer 3 : 123

Android指南并未特别提及此类问题。我想知道,我们应该使用Anonymous class还是Lambda来观察LiveData

1 个答案:

答案 0 :(得分:2)

最好不要在每次点击按钮时创建新的观察者。而是将其从单击回调中取出并将其放入Activity / Fragment初始化代码中。例如,进入您的onCreate活动方法。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mainViewModel.getCounter().observe(MainFragment.this, new Observer<Integer>() {
        @Override
        public void onChanged(@Nullable Integer counter) {
            android.util.Log.i("CHEOK", "Observer 3 : " + counter + ", " + this);
        }
    });
}

然后,为了递增计数器,您需要告诉ViewModel数据应该更改。在您的情况下mainViewModel.incrementCounter();。如果您还使用存储库设计模式,则应在mainRepository.incrementCounter();中调用ViewModel

此时,您可以访问MutableLiveData<Integer>实例并增加它。使用postValue(...)方法通常是个好主意,因为它会通过主线程发送更新。这对UI更新非常重要。

(并回答你的最终问题:它真的不应该重要你是否使用匿名或lambdas,虽然lambdas只是更漂亮 - 做我上面提到的改变应该清理你的主要问题虽然)