Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Observable vs. LiveData
Search
Seiya Kokushi
February 27, 2018
Technology
1.3k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Observable vs. LiveData
Seiya Kokushi
February 27, 2018
More Decks by Seiya Kokushi
See All by Seiya Kokushi
OS 標準のデザインシステムを超えて - より柔軟な Flutter テーマ管理 | FlutterKaigi 2024
ronnnnn
0
1.8k
Kotlin/NativeのNew Memory Managerに移行しよう | Kotlin Fest 2022
ronnnnn
0
830
Kotlin Multiplatform MobileのおさらいとABEMAでのマルチプラットフォーム対応 | CA BASE NEXT 2022
ronnnnn
0
250
Compose Multiplatformってどうなんだろう? | Flutter × Kotlin Multiplatform by CyberAgent #7
ronnnnn
0
1k
Multiplatform Engineering Roadmap for the Future | ABEMA Developer Conference 2021
ronnnnn
0
130
エンジニアとしてのプロダクト貢献
ronnnnn
2
100k
事業を伸ばすためにエンジニアとして何ができるか
ronnnnn
3
2.3k
Other Decks in Technology
See All in Technology
AI時代の開発生産性は、個人技からチーム設計へ
moongift
PRO
2
230
LLMやAIエージェントをソフトウェアに組み込むプラクティス
shibuiwilliam
1
360
ゴールデンパスは敷いただけでは道にならない ─ 企画部門のエンジニアが技術標準を事業価値に変えるまで
mhrtech
0
140
AI Agent SaaS を支える自社仮想化基盤への挑戦と実運用 / ai-agent-saas-virtualization
flatt_security
2
3.8k
【Claude Code】鹿野さんに聞く 私の推しの並行開発環境 大公開 / claude-code-parallel-2026-07-15
tonkotsuboy_com
11
7.1k
プロダクトだけじゃない、社内プロセスにおける自動化・省力化ノススメ
kakehashi
PRO
1
3.7k
10年目を迎えた「ABEMA」がどのように AI 活用を推進して、AI 駆動開発にシフトしているのか / How ABEMA, entering its 10th year, is promoting the use of AI and shifting toward AI-driven development
miyukki
0
130
ruby.wasmとPicoRuby.wasmに対応した仮想DOMライブラリを作ってる話 #kaigieffect_kaigi
sue445
PRO
0
140
ソニー銀行におけるビジネスアジリティ向上のためのクラウドシフト戦略
srenext
0
190
公式ドキュメントの歩き方etc
coco_se
0
100
関数型の考えを TypeScript に持ち込んで、テストしやすい純粋関数を増やす / Pure at the Core, Effects at the Edge: Bringing Functional Thinking into TypeScript
kaminashi
1
110
Compose 新機能総まとめ / What's New in Jetpack Compose
yanzm
0
170
Featured
See All Featured
Code Reviewing Like a Champion
maltzj
528
40k
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
630
A designer walks into a library…
pauljervisheath
211
24k
Neural Spatial Audio Processing for Sound Field Analysis and Control
skoyamalab
0
370
Visual Storytelling: How to be a Superhuman Communicator
reverentgeek
2
590
How to make the Groovebox
asonas
2
2.3k
The Language of Interfaces
destraynor
162
27k
Testing 201, or: Great Expectations
jmmastey
46
8.2k
Noah Learner - AI + Me: how we built a GSC Bulk Export data pipeline
techseoconnect
PRO
0
220
Embracing the Ebb and Flow
colly
88
5.1k
How to build a perfect <img>
jonoalderson
1
5.8k
Transcript
Observable vs. LiveData CA.apk #5 Seiya Kokushi
Seiya Kokushi ronnnnn ronnnnn_jp
Motivation
ある日のMTGにて.. それじゃあ、ViewとViewModelは Observableでやりとりしましょ! さんせ〜い!! よーし、新しいアーキテクチャは MVVMを採用するぞ〜!
な、なぜLiveDataじゃないんだ!! そもそも、ObservableとLiveDataの 違いって何だ〜!!!
Overview
✂ ✂ Observable LiveData - android.databinding - interface - BaseObservable
ObservableField<T> ObservableXxx ObservableListなど - bindable - android.arch.lifecycle - abstract class - MutableLiveData<T>など - lifecycle aware
Pros and cons
View ViewModel Observable LiveData Data action fetch flowable observe update
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にセット
<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
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(); } } }
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; } }
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
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
- 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); }
LiveData - Lifecycle Aware - 厳密な画面遷移には不向き - LiveDataはonPauseの後に購読解除される -
onSaveInstanceState後の画面遷移を再現できない googlesamples/android-architecture-components/issues/63
Plus one
None
None
None
sample project ronnnnn/AndroidSamples observable livedata livedatabinding (AS 3.1 canary 6+)