Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Observable vs. LiveData

Avatar for Seiya Kokushi Seiya Kokushi
February 27, 2018

Observable vs. LiveData

Avatar for Seiya Kokushi

Seiya Kokushi

February 27, 2018
Tweet

More Decks by Seiya Kokushi

Other Decks in Technology

Transcript

  1. ✂ ✂ Observable LiveData - android.databinding - interface - BaseObservable


    ObservableField<T>
 ObservableXxx
 ObservableListなど - bindable - android.arch.lifecycle - abstract class - MutableLiveData<T>など - lifecycle aware
  2. Observable class MainViewModel @Inject constructor( private val randomUseCase: RandomUseCase )

    : ViewModel() { val title: ObservableField<String> = ObservableField("") val imageUrl: ObservableField<String> = 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にセット
  3. <layout > <data> <variable name="viewModel" type="com.ronnnnn.androidsamples.ui.MainViewModel" /> </data> <RelativeLayout >

    <Button android:onClick="@{() -> viewModel.updateRandom()}” /> <TextView android:text="@{viewModel.title}" /> <ImageView imageUrl="@{viewModel.imageUrl}" /> </RelativeLayout> </layout> 値に変更があったら
 viewのpropertyが変更される Observable
  4. Observable - DataBindingを最大限活用できる - オブジェクトに変更があった時のみ、値を通知する public class ObservableField<T> extends BaseObservable

    implements Serializable { … private T mValue; … /** * Set the stored value. */ public void set(T value) { if (value != mValue) { mValue = value; notifyChange(); } } }
  5. Observable - Lifecycle Awareじゃない 
 - メモリリーク..? 
 - 値変更のlistenerが


    WeakReferenceを継承 - 画面遷移には不向き 
 - 最新の値をキャッシュする
 ので、戻るとまた遷移する private static class WeakListener<T> extends WeakReference<ViewDataBinding> { private final ObservableReference<T> 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; } }
  6. LiveData class MainViewModel @Inject constructor( private val randomUseCase: RandomUseCase )

    : ViewModel() { val title: MutableLiveData<String> = MutableLiveData() val imageUrl: MutableLiveData<String> = 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
  7. class MainActivity : AppCompatActivity() { … override fun onCreate(savedInstanceState: Bundle?)

    { super.onCreate(savedInstanceState) component.inject(this) val binding = DataBindingUtil.setContentView<ActivityMainBinding>(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
  8. - 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); }
  9. LiveData - Lifecycle Aware - 厳密な画面遷移には不向き 
 - LiveDataはonPauseの後に購読解除される
 -

    onSaveInstanceState後の画面遷移を再現できない googlesamples/android-architecture-components/issues/63