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
Inside Architecture Components
Search
kobito-kaba
February 07, 2018
Programming
4
4k
Inside Architecture Components
Lifecycle, LiveData, ViewModelの使いかたとその仕組みについて
kobito-kaba
February 07, 2018
Tweet
Share
More Decks by kobito-kaba
See All by kobito-kaba
新規プロジェクトでやってよかったことまとめ
kobitokaba
1
750
Youtube like BottomNavigation
kobitokaba
0
180
Modularizing and Refactoring Android App with Clean Architecture
kobitokaba
0
220
Slice Your App
kobitokaba
2
1.1k
Inside Jetpack
kobitokaba
2
95
Generating and Transforming Kotlin code
kobitokaba
0
66
Conference Tourism
kobitokaba
0
230
Inside Jetpack Architecture Components
kobitokaba
0
190
Kotlinもう一歩
kobitokaba
8
15k
Other Decks in Programming
See All in Programming
初めてDefinitelyTypedにPRを出した話
syumai
0
390
EventSourcingの理想と現実
wenas
6
2.3k
Enabling DevOps and Team Topologies Through Architecture: Architecting for Fast Flow
cer
PRO
0
300
OnlineTestConf: Test Automation Friend or Foe
maaretp
0
100
Contemporary Test Cases
maaretp
0
130
Nurturing OpenJDK distribution: Eclipse Temurin Success History and plan
ivargrimstad
0
800
Realtime API 入門
riofujimon
0
150
AWS Lambdaから始まった Serverlessの「熱」とキャリアパス / It started with AWS Lambda Serverless “fever” and career path
seike460
PRO
1
250
ピラミッド、アイスクリームコーン、SMURF: 自動テストの最適バランスを求めて / Pyramid Ice-Cream-Cone and SMURF
twada
PRO
10
1.2k
광고 소재 심사 과정에 AI를 도입하여 광고 서비스 생산성 향상시키기
kakao
PRO
0
170
開発効率向上のためのリファクタリングの一歩目の選択肢 ~コード分割~ / JJUG CCC 2024 Fall
ryounasso
0
450
Jakarta EE meets AI
ivargrimstad
0
520
Featured
See All Featured
Build The Right Thing And Hit Your Dates
maggiecrowley
33
2.4k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.2k
Visualization
eitanlees
145
15k
Reflections from 52 weeks, 52 projects
jeffersonlam
346
20k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
38
1.8k
Save Time (by Creating Custom Rails Generators)
garrettdimon
PRO
27
830
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
16
2.1k
Faster Mobile Websites
deanohume
305
30k
The Power of CSS Pseudo Elements
geoffreycrofte
73
5.3k
Practical Orchestrator
shlominoach
186
10k
Bash Introduction
62gerente
608
210k
What's in a price? How to price your products and services
michaelherold
243
12k
Transcript
Inside Architecture Components Yahoo! JAPAN / 森 洋之
About me 森 洋之 @moridroid Yahoo! JAPAN Androidアプリ黒帯 (こういうところで話す仕事)
About me 森 洋之 @moridroid Yahoo! JAPAN Androidアプリ黒帯 (こういうところで話す仕事) ヤフオク!のアプリ担当
About me 森 洋之 @moridroid Yahoo! JAPAN Androidアプリ黒帯 (こういうところで話す仕事) ヤフオク!のアプリ担当 Yahoo! JAPANブースで本を配っています
About me 森 洋之 @moridroid Yahoo! JAPAN Androidアプリ黒帯 (こういうところで話す仕事) ヤフオク!のアプリ担当 Yahoo! JAPANブースで本を配っています
(おすすめしません)
今日の話のまとめ
今日の話のまとめ ・Lifecycle matters
今日の話のまとめ ・Lifecycle is matter ・各コンポーネント紹介
今日の話のまとめ ・Lifecycle is matter ・各コンポーネント紹介 ・どう動いているか
今日の話のまとめ ・Lifecycle is matter ・各コンポーネント紹介 ・どう動いているか ・どう付き合っていくか
Architecture Components
Why Architecture Components
Why Architecture Components Activity Service BroadcastReceiver ContentProvider
Why Architecture Components Activity Service BroadcastReceiver ContentProvider is
Why Architecture Components Activity Service BroadcastReceiver ContentProvider is
Why Architecture Components MVC 提供:アフロ
Why Architecture Components MVC MVP 提供:アフロ
Why Architecture Components MVC MVP MVVM Flux 提供:アフロ
Why Architecture Components MVC MVP MVVM Flux Clean Architecture 提供:アフロ
Why Architecture Components MVC MVP Flux Clean Architecture 提供:アフロ MVVM
Why Architecture Components 提供:アフロ
Why Architecture Components 提供:アフロ
Why Architecture Components
What’s Architecture Components
Architecture Components ・Lifecycle ・LiveData ・ViewModel ・Room
・Paging
Architecture Components → ライフサイクルイベントを通知する ・Lifecycle ・LiveData ・ViewModel ・Room
・Paging
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータホルダー ・Lifecycle ・LiveData
・ViewModel ・Room ・Paging
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータホルダー → アクティビティ再生成後もデータを維持する ・Lifecycle ・LiveData
・ViewModel ・Room ・Paging
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータホルダー → アクティビティ再生成後もデータを維持する → SQLite用オブジェクトマッパー ・Lifecycle
・LiveData ・ViewModel ・Room ・Paging
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータホルダー → アクティビティ再生成後もデータを維持する → SQLite用オブジェクトマッパー → ちょっとずつデータを取り出して
Adapterに流す ・Lifecycle ・LiveData ・ViewModel ・Room ・Paging
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータ → アクティビティ再生成後もデータを維持する → SQLite用オブジェクトマッパー → ちょっとずつデータを取り出して
Adapterに流す ・Lifecycle ・LiveData ・ViewModel ・Room ・Paging 今日やるところ
Architecture Components → ライフサイクルイベントを通知する → 変更を通知してくれるデータ → アクティビティ再生成後もデータを維持する → SQLite用オブジェクトマッパー → ちょっとずつデータを取り出して
Adapterに流す ・Lifecycle ・LiveData ・ViewModel ・Room ・Paging 今日やるところ Lifecycleグループ
Lifecycle matters
Lifecycle matters in old days... https://developer.android.com/guide/components/activities/activity-lifecycle.html
Lifecycle matters today Steve Pomeroy https://github.com/xxv/android-lifecycle CC-BY-SA 4.0
Lifecycle matters ・ネットワーク通信して、データとってきたけど 画面回転したから無駄になった
Lifecycle matters ・ネットワーク通信して、データとってきたけど 画面回転したから無駄になった ・ネットワーク通信して、データとってくる途中で 画面回転したら、表示するビューは破棄されてて クラッシュした
Lifecycle matters ・ネットワーク通信して、データとってきたけど 画面回転したから無駄になった ・ネットワーク通信して、データとってくる途中で 画面回転したら、表示するビューは破棄されてて クラッシュした ・というか一般的に、非同期的な処理を行うクラスに ViewやActivityContextをもたせたらダメ
Lifecycle matters ・データの変更を監視してViewを更新させようと したらメモリリークした
Lifecycle matters ・データの変更を監視してViewを更新させようと したらメモリリークした ・変更を検知してViewを更新しようとしたら すでに破棄されてた
Lifecycle matters ・データの変更を監視してViewを更新させようと したらメモリリークした ・変更を検知してViewを更新しようとしたら すでに破棄されてた ・これらに対処したら、onResumeやonPauseが ボイラープレートだらけになった
Lifecycle matters ・ロジックを分離する
例題
例題
例題 一般例
例題 class NetworkStateReceiver(private val callback : (NetworkInfo?) -> Unit) :
BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val conn = context?.getSystemService(Context.CONNECTIVITY_SERVICE) as? ConnectivityManager ?: return callback(conn.activeNetworkInfo) } }
class MainActivity : AppCompatActivity() { private lateinit var receiver: NetworkStateReceiver
private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) textView = findViewById(R.id.textView) receiver = NetworkStateReceiver { if (it != null && it.isConnected) { textView.text = "online" } else { textView.text = "offline" } } } 例題 override fun onResume() { super.onResume() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) registerReceiver(receiver, filter) } override fun onPause() { super.onPause() unregisterReceiver(receiver) } }
class MainActivity : AppCompatActivity() { private lateinit var receiver: NetworkStateReceiver
private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) textView = findViewById(R.id.textView) receiver = NetworkStateReceiver { if (it != null && it.isConnected) { textView.text = "online" } else { textView.text = "offline" } } } 例題 override fun onResume() { super.onResume() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) registerReceiver(receiver, filter) } override fun onPause() { super.onPause() unregisterReceiver(receiver) } } Activityのロジックと混在する
class MainActivity : AppCompatActivity() { private lateinit var receiver: NetworkStateReceiver
private lateinit var textView: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) textView = findViewById(R.id.textView) receiver = NetworkStateReceiver { if (it != null && it.isConnected) { textView.text = "online" } else { textView.text = "offline" } } } 例題 override fun onResume() { super.onResume() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) registerReceiver(receiver, filter) } override fun onPause() { super.onPause() unregisterReceiver(receiver) } } Activityのロジックと混在する Activity / Fragmentごとに書くの嫌
Lifecycle
Lifecycle lifecycleパッケージの中核的なコンポーネント
Lifecycle lifecycleパッケージの中核的なコンポーネント Activity / Fragmentなどのライフサイクルイベント時に処 理を差し挟める
Lifecycle lifecycleパッケージの中核的なコンポーネント Activity / Fragmentなどのライフサイクルイベント時に処 理を差し挟める ActivityLifecycleCallbacks、 FragmentLifecycleCallbacksってあったよね…?
ActivityLifecycleCallbacks Lifecycle
Lifecycle ActivityLifecycleCallbacks →アプリ内の全アクティビティの ライフサイクルイベントを拾う
Lifecycle ActivityLifecycleCallbacks →アプリ内の全アクティビティの ライフサイクルイベントを拾う →こういう目的じゃない
Lifecycle FragmentLifecycleCallbacks →アクティビティ内の全フラグメントの ライフサイクルイベントを拾う →こういう目的じゃない
Lifecycle ・ライフサイクルイベントに関係する処理を Activity / Fragmentから切り離すことができる!
Lifecycle ・ライフサイクルイベントに関係する処理を Activity / Fragmentから切り離すことができる! ・内部実装を読んで面白い!
Lifecyleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
Lifecycleの仕組み
使いかた
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { callback(Connectivity.ONLINE) } else { callback(Connectivity.OFFLINE) } } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 使いかた @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } } enum class Connectivity { OFFLINE, ONLINE }
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた 普通はこうする。作るの楽だから。 interface LifecycleObserver { fun onCreate() {} fun onResume() {} fun onPause() {} fun onDestroy() {} // ... }
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた 要らないイベント省略可
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた 要らないイベント省略可 メソッド名 = 処理内容
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { 〜〜 @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 〜〜 } 使いかた 要らないイベント省略可 メソッド名 = 処理内容 複数のメソッドに分割
使いかた class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView = findViewById<TextView>(R.id.textView) val networkObservable = NetworkObservable(this) { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } } lifecycle.addObserver(networkObservable) } }
余談
余談 ・バイトコード変換
余談 class FooObservable() : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun fooMethod() { 〜〜 }
}
余談 class FooObservable() : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun fooMethod() { 〜〜 }
fun onResume() { registerReceiver() } }
余談 ・バイトコード変換 ・Annotation Processor
余談 class FooObservable() : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun fooMethod() { 〜〜 }
}
余談 class FooObservable() : LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun fooMethod() { 〜〜 }
} class FooObservableAdapter(private val target : FooObservable) : LifecycleObserver { fun onResume() { target.fooMethod() } }
余談 ・バイトコード変換 ・Annotation Processor ・Reflection
余談 ・バイトコード変換 ・Annotation Processor ・Reflection
余談 ・バイトコード変換 ・Annotation Processor ・Reflection 任意
Lifecyleを追え
Lifecycleを追え class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ 〜〜 lifecycle.addObserver(networkObservable) } }
Lifecycleを追え networkObservable SupportActivity addObserver call method
Lifecycleを追え networkObservable SupportActivity addObserver call method
@Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState =
mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); 〜〜 } Lifecycleを追え
@Override public void addObserver(@NonNull LifecycleObserver observer) { State initialState =
mState == DESTROYED ? DESTROYED : INITIALIZED; ObserverWithState statefulObserver = new ObserverWithState(observer, initialState); ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver); 〜〜 } Lifecycleを追え
static class ObserverWithState { State mState; GenericLifecycleObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer,
State initialState) { mLifecycleObserver = Lifecycling.getCallback(observer); mState = initialState; } void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } } Lifecycleを追え
static class ObserverWithState { State mState; GenericLifecycleObserver mLifecycleObserver; ObserverWithState(LifecycleObserver observer,
State initialState) { mLifecycleObserver = Lifecycling.getCallback(observer); mState = initialState; } void dispatchEvent(LifecycleOwner owner, Event event) { State newState = getStateAfter(event); mState = min(mState, newState); mLifecycleObserver.onStateChanged(owner, event); mState = newState; } } Lifecycleを追え
static GenericLifecycleObserver getCallback(Object object) { 〜〜 int type = getObserverConstructorType(klass);
if (type == GENERATED_CALLBACK) { 〜〜 return アノテーションプロセッサを使った場合用のクラス } return リフレクションを使う場合のクラス } Lifecycleを追え
public class SupportActivity extends Activity implements LifecycleOwner { 〜〜 @Override
@SuppressWarnings("RestrictedApi") protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); } 〜〜 } Lifecycleを追え
public class ReportFragment extends Fragment { @Override public void onActivityCreated(Bundle
savedInstanceState) { dispatch(Lifecycle.Event.ON_CREATE); } 〜〜 } Lifecycleを追え
Lifecycleを追え public class ReportFragment extends Fragment { private void dispatch(Lifecycle.Event
event) { 〜〜 if (activity instanceof LifecycleOwner) { Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle(); if (lifecycle instanceof LifecycleRegistry) { ((LifecycleRegistry) lifecycle).handleLifecycleEvent(event); } } } }
Lifecycleを追え ObserverWithState AdapterObserver Adapter FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach
dispatch event sync
Lifecycleを追え ReportFragment SupportActivity LifecycleRegistry attach dispatch event
Lifecycleを追え ReportFragment SupportActivity LifecycleRegistry FooObserver addObserver attach dispatch event
Lifecycleを追え ObserverWithState AdapterObserver Adapter FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach
dispatch event sync
Lifecycleを追え Subscriber Publisher EventChannel subscribe publish event fire event
LiveData
LiveData ・オブザーバブルなデータホルダー
LiveData ・オブザーバブルなデータホルダー ・Activity / Fragmentのライフサイクルを尊重する
使いかた
class NetworkObservable(private var activity: Activity?, private val callback : (Connectivity)
-> Unit) : LifecycleObserver { private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { callback(Connectivity.ONLINE) } else { callback(Connectivity.OFFLINE) } } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } 使いかた @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } }
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } 使いかた @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } } }
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity 〜〜 } 使いかた
class NetworkObservable(private var activity: Activity?) : LifecycleObserver { private val
connectivity = MutableLiveData<Connectivity>() private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { connectivity.postValue(Connectivity.ONLINE) } else { connectivity.postValue(Connectivity.OFFLINE) } } fun getConnectivity() : LiveData<Connectivity> = connectivity 〜〜 } 使いかた
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
〜〜 val observable = NetworkObservable(this) observable.getConnectivity().observe(this, Observer<Connectivity> { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) lifecycle.addObserver(observable) } } 使いかた
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
〜〜 val observable = NetworkObservable(this) observable.getConnectivity().observe(this, Observer<Connectivity> { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) lifecycle.addObserver(observable) } } 使いかた
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
〜〜 val observable = NetworkObservable(this) observable.getConnectivity().observe(this, Observer<Connectivity> { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) lifecycle.addObserver(observable) } } 使いかた
LiveDataを追え
LiveDataを追え class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?)
{ 〜〜 val observable = NetworkObservable(this) observable.getConnectivity().observe(this, Observer<Connectivity> { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) lifecycle.addObserver(observable) } }
LiveData public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
〜〜 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); 〜〜 owner.getLifecycle().addObserver(wrapper); }
LiveData public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
〜〜 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); 〜〜 owner.getLifecycle().addObserver(wrapper); }
LiveData public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
〜〜 LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer); ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper); 〜〜 owner.getLifecycle().addObserver(wrapper); }
LiveData class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver { 〜〜 @Override
boolean shouldBeActive() { return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED); } 〜〜 }
LiveData protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData =
value; dispatchingValue(null); }
LiveData protected void setValue(T value) { assertMainThread("setValue"); mVersion++; mData =
value; dispatchingValue(null); }
Lifecycleを追え LifecycleBoundObserver FooObserver addObserver sync LifecycleOwner LiveData observe dispatch
Lifecycleを追え FooObserver LifecycleOwner LiveData observe
Lifecycleを追え LifecycleBoundObserver FooObserver LifecycleOwner LiveData observe
Lifecycleを追え LifecycleBoundObserver FooObserver addObserver LifecycleOwner LiveData observe
Lifecycleを追え LifecycleBoundObserver FooObserver addObserver LiveData observe sync LifecycleOwner
Lifecycleを追え LifecycleBoundObserver FooObserver addObserver LiveData observe sync LifecycleOwner dispatch
ViewModel
・retained FragmentにViewModelを持たせる ViewModel
・retained FragmentにViewModelを持たせる ・Activityが再生成しても、 retained Fragmentはインスタンスを維持する ViewModel
・retained FragmentにViewModelを持たせる ・Activityが再生成しても、 retained Fragmentはインスタンスを維持する ・そのため、ViewModelも破棄されない ViewModel
ViewModel ・retained FragmentにViewModelを持たせる ・Activityが再生成しても、 retained Fragmentはインスタンスを維持する ・そのため、ViewModelも破棄されない ・以上!
使いかた
・ActivityのContextやViewを持たせてはダメ 注意点
・ActivityのContextやViewを持たせてはダメ ・同一のViewModelクラスは、 アクティビティ内で1インスタンス 注意点
・ActivityのContextやViewを持たせてはダメ ・同一のViewModelクラスは、 アクティビティ内で1インスタンス 注意点
使いかた class NetworkObservable(private var activity: Activity?, private val callback :
(Connectivity) -> Unit) : LifecycleObserver { private val receiver = NetworkStateReceiver { if (it != null && it.isConnected) { callback(Connectivity.ONLINE) } else { callback(Connectivity.OFFLINE) } } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) activity?.registerReceiver(receiver, filter) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver() { activity?.unregisterReceiver(receiver) } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } } enum class Connectivity { OFFLINE, ONLINE }
使いかた class NetworkViewModel : ViewModel() { val connectivity = MutableLiveData<Connectivity>()
}
使いかた class NetworkViewModel : ViewModel() { val connectivity = MutableLiveData<Connectivity>()
}
使いかた class NetworkViewModel : ViewModel() { val connectivity = MutableLiveData<Connectivity>()
}
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView = findViewById<TextView>(R.id.textView) val viewModel = ViewModelProviders.of(this).get(NetworkViewModel::class.java) viewModel.connectivity.observe(this, Observer<Connectivity> { when(it) { Connectivity.ONLINE -> textView.text = "online" Connectivity.OFFLINE -> textView.text = "offline" } }) val networkObservable = NetworkObservable(this) { viewModel.connectivity.postValue(it) } lifecycle.addObserver(networkObservable) } } 使いかた
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView = findViewById<TextView>(R.id.textView) val viewModel = ViewModelProviders.of(this).get(NetworkViewModel::class.java) viewModel.connectivity.observe(this, Observer<Connectivity> { when(it) { Connectivity.ONLINE -> textView.text = "online" Connectivity.OFFLINE -> textView.text = "offline" } }) val networkObservable = NetworkObservable(this) { viewModel.connectivity.postValue(it) } lifecycle.addObserver(networkObservable) } } 使いかた
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val textView = findViewById<TextView>(R.id.textView) val viewModel = ViewModelProviders.of(this).get(NetworkViewModel::class.java) viewModel.connectivity.observe(this, Observer<Connectivity> { when(it) { Connectivity.ONLINE -> textView.text = "online" Connectivity.OFFLINE -> textView.text = "offline" } }) val networkObservable = NetworkObservable(this) { viewModel.connectivity.postValue(it) } lifecycle.addObserver(networkObservable) } } 使いかた
ViewModelを追え
追いません
まとめ
まとめ ・Architecture Components誕生の背景
まとめ ・Architecture Components誕生の背景 ・Lifecycle Matters
まとめ ・Architecture Components誕生の背景 ・Lifecycle Matters ・各コンポーネントの使いかた
まとめ ・Architecture Components誕生の背景 ・Lifecycle Matters ・各コンポーネントの使いかた ・と、その仕組
Thank you