Slide 1

Slide 1 text

Observable vs. LiveData CA.apk #5 Seiya Kokushi

Slide 2

Slide 2 text

Seiya Kokushi ronnnnn ronnnnn_jp

Slide 3

Slide 3 text

Motivation

Slide 4

Slide 4 text

ある日のMTGにて.. それじゃあ、ViewとViewModelは
 Observableでやりとりしましょ! さんせ〜い!! よーし、新しいアーキテクチャは
 MVVMを採用するぞ〜!

Slide 5

Slide 5 text

な、なぜLiveDataじゃないんだ!!
 そもそも、ObservableとLiveDataの
 違いって何だ〜!!!

Slide 6

Slide 6 text

Overview

Slide 7

Slide 7 text

✂ ✂ Observable LiveData - android.databinding - interface - BaseObservable
 ObservableField
 ObservableXxx
 ObservableListなど - bindable - android.arch.lifecycle - abstract class - MutableLiveDataなど - lifecycle aware

Slide 8

Slide 8 text

Pros and cons

Slide 9

Slide 9 text

View ViewModel Observable
 LiveData Data action fetch flowable observe update

Slide 10

Slide 10 text

Observable class MainViewModel @Inject constructor( private val randomUseCase: RandomUseCase ) : ViewModel() { val title: ObservableField = ObservableField("") val imageUrl: ObservableField = ObservableField("") …
 init { randomUseCase.observe() .subscribeOn(Schedulers.io()) .subscribe({ randomData -> title.set(randomData.data.title) imageUrl.set(randomData.data.images.downsizedMedium.url) }) .let { compositeDisposable.add(it) } fetchRandomData() } … } 監視したいオブジェクトを
 Observableで宣言 値が流れてきたら
 値をObservableにセット

Slide 11

Slide 11 text

値に変更があったら
 viewのpropertyが変更される Observable

Slide 12

Slide 12 text

Observable - DataBindingを最大限活用できる - オブジェクトに変更があった時のみ、値を通知する public class ObservableField extends BaseObservable implements Serializable { … private T mValue; … /** * Set the stored value. */ public void set(T value) { if (value != mValue) { mValue = value; notifyChange(); } } }

Slide 13

Slide 13 text

Observable - Lifecycle Awareじゃない 
 - メモリリーク..? 
 - 値変更のlistenerが
 WeakReferenceを継承 - 画面遷移には不向き 
 - 最新の値をキャッシュする
 ので、戻るとまた遷移する private static class WeakListener extends WeakReference { private final ObservableReference mObservable; protected final int mLocalFieldId; private T mTarget; … public boolean unregister() { boolean unregistered = false; if (mTarget != null) { mObservable.removeListener(mTarget); unregistered = true; } mTarget = null; return unregistered; } … protected ViewDataBinding getBinder() { ViewDataBinding binder = get(); if (binder == null) { unregister(); // The binder is dead } return binder; } }

Slide 14

Slide 14 text

LiveData class MainViewModel @Inject constructor( private val randomUseCase: RandomUseCase ) : ViewModel() { val title: MutableLiveData = MutableLiveData() val imageUrl: MutableLiveData = MutableLiveData() … init { randomUseCase.observe() .subscribeOn(Schedulers.io()) .subscribe({ randomData -> title.postValue(randomData.data.title) imageUrl.postValue(randomData.data.images.downsizedMedium.url) }) .let { compositeDisposable.add(it) } fetchRandomData() } … } 監視したいオブジェクトを
 LiveDataで宣言 値が流れてきたら
 値をLiveDataにpost

Slide 15

Slide 15 text

class MainActivity : AppCompatActivity() { … override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) component.inject(this) val binding = DataBindingUtil.setContentView(this, R.layout.activity_main).apply { viewModel = mainViewModel } mainViewModel.imageUrl.observe(this, Observer { it ?: return@Observer binding.gifImageView.load(it) }) mainViewModel.title.observe(this, Observer { it ?: return@Observer binding.titleTextView.text = it }) } … } 値が通知されたら
 viewのpropertyを更新する LiveData

Slide 16

Slide 16 text

- DataBindingを最大限活用できない - オブジェクトに変更がなくても、値を通知する LiveData protected void postValue(T value) { boolean postTask; synchronized (mDataLock) { postTask = mPendingData == NOT_SET; mPendingData = value; } if (!postTask) { return; } ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable); } @MainThread protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData = value; dispatchingValue(null); }

Slide 17

Slide 17 text

LiveData - Lifecycle Aware - 厳密な画面遷移には不向き 
 - LiveDataはonPauseの後に購読解除される
 - onSaveInstanceState後の画面遷移を再現できない googlesamples/android-architecture-components/issues/63

Slide 18

Slide 18 text

Plus one

Slide 19

Slide 19 text

No content

Slide 20

Slide 20 text

No content

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

sample project ronnnnn/AndroidSamples observable livedata livedatabinding (AS 3.1 canary 6+)