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 LifecycleObserver
Search
kobito-kaba
July 18, 2018
0
80
Inside LifecycleObserver
How to handle components' lifecycle in Android app developing.
kobito-kaba
July 18, 2018
Tweet
Share
More Decks by kobito-kaba
See All by kobito-kaba
新規プロジェクトでやってよかったことまとめ
kobitokaba
1
730
Youtube like BottomNavigation
kobitokaba
0
180
Modularizing and Refactoring Android App with Clean Architecture
kobitokaba
0
210
Slice Your App
kobitokaba
2
1.1k
Inside Jetpack
kobitokaba
2
92
Generating and Transforming Kotlin code
kobitokaba
0
64
Conference Tourism
kobitokaba
0
230
Inside Jetpack Architecture Components
kobitokaba
0
190
Kotlinもう一歩
kobitokaba
8
15k
Featured
See All Featured
Building Better People: How to give real-time feedback that sticks.
wjessup
363
19k
Navigating Team Friction
lara
183
14k
GitHub's CSS Performance
jonrohan
1030
460k
Practical Orchestrator
shlominoach
186
10k
Building Applications with DynamoDB
mza
90
6.1k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
107
49k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Thoughts on Productivity
jonyablonski
67
4.3k
Building a Scalable Design System with Sketch
lauravandoore
459
33k
KATA
mclloyd
29
13k
Agile that works and the tools we love
rasmusluckow
327
21k
The Cost Of JavaScript in 2023
addyosmani
45
6.6k
Transcript
Hiroyuki Mori @moridroid Inside LifecycleObserver
Lifecycle Problems in Android
in early days https://developer.android.com/guide/components/activities/activity-lifecycle.html
today Steve Pomeroy https://github.com/xxv/android-lifecycle CC-BY-SA 4.0
case 1: fetching data every onCreate
case 1: fetching data every onCreate
case 1: fetching data every onCreate
case 1: fetching data every onCreate
case 1: fetching data every onCreate
case 1: fetching data every onCreate Wasteful
case 2: showing after activity’s death
case 2: showing after activity’s death
case 2: showing after activity’s death
case 2: showing after activity’s death Crash !!
case 3: forgetting to stop observing
case 3: forgetting to stop observing
case 3: forgetting to stop observing
case 3: forgetting to stop observing memory leak
Handling lifecycles
Lifecycle library
Observer pattern
None
None
None
None
None
None
×
None
None
None
loose coupled
None
None
Event Channel
None
notify events
observe
None
Inside Lifecycle library
subscribing lifecycle events
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
... lifecycle.addObserver(yourObservable) } }
public class LifecycleRegistry extends 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);
public class LifecycleRegistry extends 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);
static class ObserverWithState { ... ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer); ... } void dispatchEvent(LifecycleOwner owner, Event event) { ... mLifecycleObserver.onStateChanged(owner, event); ... } }
static class ObserverWithState { ... ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.getCallback(observer); ... } void dispatchEvent(LifecycleOwner owner, Event event) { ... mLifecycleObserver.onStateChanged(owner, event); ... } }
publishing lifecycle events
public class SupportActivity extends Activity implements LifecycleOwner { ... protected
void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ReportFragment.injectIfNeededIn(this); } ... }
public class ReportFragment extends Fragment { ... public void onActivityCreated(Bundle
savedInstanceState) { dispatch(Lifecycle.Event.ON_CREATE); } public void onStart() { dispatch(Lifecycle.Event.ON_START); } public void onResume() { dispatch(Lifecycle.Event.ON_RESUME); } public void onPause() { dispatch(Lifecycle.Event.ON_PAUSE); } public void onStop() { dispatch(Lifecycle.Event.ON_STOP); } ... }
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); } } } }
ObserverWithState AdapterObserver Adapter FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach dispatch
event sync
ReportFragment SupportActivity LifecycleRegistry attach dispatch event
FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach dispatch event
ObserverWithState AdapterObserver Adapter FooObserver ReportFragment SupportActivity LifecycleRegistry addObserver attach dispatch
event sync
Subscriber Publisher EventChannel subscribe publish event fire event
How to use
example: Observing network state
None
None
without LifecycleObserver
class NetworkStateReceiver(private val callback : (NetworkInfo?) -> Unit) : BroadcastReceiver()
{ override fun onReceive(context: Context?, intent: Intent?) { val conn = context?.getSystemService(ConnectivityManager::class.java) ?: return callback(conn.activeNetworkInfo) } } Step1 : Create a BroadcastReceiver
receiver = NetworkStateReceiver { if (it != null && it.isConnected)
{ textView.text = "online" } else { textView.text = "offline" } } Step2 : create an instance create an instance
Step3 : register it at onResume override fun onResume() {
super.onResume() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION) registerReceiver(receiver, filter) } register at onResume
override fun onPause() { super.onPause() unregisterReceiver(receiver) } Step4 : unregister
it at onPause unregister at onPause
override fun onPause() { super.onPause() unregisterReceiver(receiver) } Step5 : Never
forget to unregister unregister at onPause Don’t miss it
with LifecycleObserver
enum class Connectivity { OFFLINE, ONLINE } 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) } } } Step1 : Wrap the receiver
enum class Connectivity { OFFLINE, ONLINE } 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) } } } Step1 : Wrap the receiver implements LifecycleObserver
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { activity?.registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver()
{ activity?.unregisterReceiver(receiver) } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } Step2 : register / unregister at lifecycle events
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME) fun registerReceiver() { activity?.registerReceiver(receiver, IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)) } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) fun unregisterReceiver()
{ activity?.unregisterReceiver(receiver) } @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY) fun release() { activity = null } Step2 : register / unregister at lifecycle events @OnLifecycleEvent
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
... lifecycle.addObserver( NetworkObservable(this) { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) } } Step3 : Use it !
class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) {
... lifecycle.addObserver( NetworkObservable(this) { if (it == Connectivity.ONLINE) { textView.text = "online" } else { textView.text = "offline" } }) } } Step3 : Use it ! easy to use
Conclusion
Lifecycle Management
Lifecycle Management - is a hard and hassle task
Lifecycle Management - is a hard and hassle task -
can cause problems
Lifecycle Management - is a hard and hassle task -
can cause problems The Lifecycle library
Lifecycle Management - is a hard and hassle task -
can cause problems The Lifecycle library - provides the feature to observe lifecycles
Lifecycle Management - is a hard and hassle task -
can cause problems The Lifecycle library - provides the feature to observe lifecycles - can create lifecycle-aware components easily
Hiroyuki Mori @moridroid Thank you