SlideShare a Scribd company logo
1 of 92
Download to read offline
Deep Dive Into Android 
State Restoration
TWITTER 
@cyrilmottier 
! 
WEBSITE 
cyrilmottier.com
The story of a newbie 
Android developer
Kevin has just developed his first 
Android app
He discovers an annoying bug: 
Fields are cleared on rotate
3 options
3 options 
Don’t care
3 options 
Don’t care Block orientation
3 options 
Don’t care Block orientation Use configChanges 
Hint: all options are
1 <activity! 
2 android:name=".HomeActivity"! 
3 android:configChanges="orientation">! 
4 ! 
5 <!-- Some sweet IntentFilters. -->! 
6 ! 
7 </activity>
Kevin’s satisfied
Still having issues on…
Still having issues on… 
language changes
1 <activity! 
2 android:name=".HomeActivity"! 
3 android:configChanges="orientation! 
4 ! 
5 <!-- Some annoying IntentFilters. -->! 
6 ! 
7 </activity> 
|locale">
ANGRY! Angry Kevin is
1 <activity! 
2 android:name=".HomeActivity"! 
3 android:configChanges=“orientation|locale|! 
mcc|mnc|touchscreen|keyboard|! 
keyboardHidden|navigation|uiMode|! 
screenLayout|fontScale|screenSize|! 
smallestScreenSize">! 
4 ! 
5 <!-- Some fuc**** IntentFilters. Arrggh! -->! 
6 ! 
7 </activity>
The nightmare continues… 
Still having issues when moving the app to the background
God save the STATE
State restoration 
key components
The container 
Parcel
The container 
Parcel The content 
Primitives types 
Primitives arrays 
Parcelable
The content 
Primitives types 
Primitives arrays 
1 parcel.writeInt(1);! 
2 parcel.writeLong(2L);! 
3 parcel.writeFloat(3F);! 
4 parcel.writeString("Hi!"); 
Parcelable
1 parcel.writeIntArray(new int[]{1, 2, 3});! 
2 parcel.writeLongArray(new long[]{1L, 2L, 3L});! 
3 parcel.writeDoubleArray(new double[]{1, 2, 3});! 
4 parcel.writeStringArray(new String[]{! 
5 "Hi", "Droidcon", "guys!"! 
6 }); 
The content 
Primitives types 
Primitives arrays 
Parcelable
1 public final class Suggestion implements Parcelable {! 
2 ! 
3 public final String id;! 
4 public final String name;! 
5 public final int type;! 
6 ! 
7 public Suggestion(String id, String name, int type) {! 
8 this.id = Objects.requireNonNull(id);! 
9 this.name = Objects.requireNonNull(name);! 
10 this.type = type;! 
11 }! 
12 ! 
13 }
1 @Override! 
2 public int describeContents() {! 
3 return 0;! 
4 }! 
5 ! 
6 @Override! 
7 public void writeToParcel(Parcel dest, int flags) {! 
8 dest.writeString(id);! 
9 dest.writeString(name);! 
10 dest.writeInt(type);! 
11 }! 
12 
13 public static final Parcelable.Creator<Suggestion> CREATOR = ! 
14 new Parcelable.Creator<Suggestion>() {! 
15 public Suggestion createFromParcel(Parcel in) {! 
16 return new Suggestion(in.readString(), // ! 
17 in.readString(), //! 
18 in.readInt());! 
19 }! 
20 ! 
21 public Suggestion[] newArray(int size) {! 
22 return new Suggestion[size];! 
23 }! 
24 };
Parcelable.Creator! 
The base creator interface 
! 
Parcelable.ClassLoaderCreator! 
A creator with the ClassLoader passed on read. 
! 
ParcelableCompat & 
ParcelableCompatCreatorCallbacks! 
Compatibility stuff
Bundle 
A key-value map & type-safe Parcelable
Parcel! 
internally uses reflection 
(required to get the CREATOR instance) 
…i.e. beware Proguard
Activity level 
state restoration
onCreate(null)
onCreate(null)
: non-null Bundle 
onCreate(null) 
onSaveInstanceState( )
onCreate(null) 
onSaveInstanceState( ) 
onCreate( ) 
: non-null Bundle
onCreate(null) 
onSaveInstanceState( ) 
onCreate( ) 
onRestoreInstanceState( ) 
: non-null Bundle
onCreate(null) 
onSaveInstanceState( ) 
onCreate( ) 
onRestoreInstanceState( ) 
: non-null Bundle
onCreate(null) 
onSaveInstanceState( ) 
onCreate( ) 
onRestoreInstanceState( ) 
: non-null Bundle
What to save? 
Non persistent or non reconstructible info
1 public class SearchActivity extends Activity {! 
2 ! 
3 private static final String STATE_OUTWARD = "state:outward";! 
4 ! 
5 private DateComponents mOutward;! 
6 ! 
7 @Override! 
8 protected void onCreate(Bundle inState) {! 
9 super.onCreate(inState);! 
10 ! 
11 if (inState != null) {! 
12 DateComponents components = inState.getParcelable(STATE_OUTWARD);! 
13 if (components != null) {! 
14 setOutward(components);! 
15 }! 
16 }! 
17 }! 
18 ! 
19 @Override! 
20 protected void onSaveInstanceState(Bundle outState) {! 
21 super.onSaveInstanceState(outState);! 
22 outState.putParcelable(STATE_OUTWARD, mOutward);! 
23 }! 
24 }
onSaveInstanceState saves 
Window
onSaveInstanceState saves 
Window Fragments
onSaveInstanceState saves 
Window Fragments Dialogs
Always call the 
SUPER METHODS Android has no guards on save-related methods
android:stateNotNeeded 
For restart-on-crash apps only 
(i.e. launcher app)
Developer options 
Don’t keep activities
Developer options 
Don’t keep activities
View level 
state restoration
Android saves UI state 
AUTOMAGICALLY
Android saves UI state 
AUTOMAGICALLY (aka “It just works!™”)
Android saves UI state 
AUTOMAGICALLY (aka “It just works!™”) 
…except in some cases
Works out-of-the-box if Views 
1. Have an ID 
2. Are “save” enabled 
3. Come from the framework
It always begins with a call to 
saveHierarchyState()
EditText! 
@id/text 
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box
EditText! 
@id/text 
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
SparseArray<Parcelable>
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
SparseArray<Parcelable> 
S1 
EditText! 
@id/text
SparseArray<Parcelable> 
@id/container 
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
S1 
EditText! 
@id/text
EditText! 
@id/text 
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
S2 SparseArray<Parcelable> 
@id/container S1
SparseArray<Parcelable> 
@id/container S1 
@id/text 
S2 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
SparseArray<Parcelable> 
@id/container S1 
@id/text 
S2 
S3 
EditText! 
@id/text
SparseArray<Parcelable> 
@id/container 
@id/text 
@id/check_box 
S1 
S2 
S3 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
Controlling save 
setSaveEnabled(boolean) 
setSaveFromParentEnabled(boolean)
It always ends with a call to 
restoreHierarchyState()
SparseArray<Parcelable> 
@id/container S1 
@id/text S2 
@id/check_box S3 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
SparseArray<Parcelable> 
@id/container S1 
S2 
S3 
@id/text 
@id/check_box 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
SparseArray<Parcelable> 
@id/container S1 
S2 
@id/check_box S3 
S1 
@id/text 
EditText! 
@id/text
SparseArray<Parcelable> 
@id/container S1 
@id/text S2 
@id/check_box S3 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
EditText! 
@id/text 
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
S2 SparseArray<Parcelable> 
@id/container S1 
@id/text 
S2 
@id/check_box S3
SparseArray<Parcelable> 
@id/container S1 
@id/text S2 
@id/check_box S3 
RelativeLayout! 
@id/container 
EditText! 
@id/text 
TextView 
CheckBox! 
@id/check_box
RelativeLayout! 
@id/container 
TextView 
CheckBox! 
@id/check_box 
@id/container S1 
@id/text S2 
@id/check_box S3 
S3 
SparseArray<Parcelable> 
EditText! 
@id/text
Ensure your Views’ IDs are 
unique & constant
1 static class SavedState extends BaseSavedState {! 
2 int checked;! 
3 ! 
4 SavedState(Parcelable superState) { super(superState); }! 
5 ! 
6 private SavedState(Parcel in) {! 
7 super(in);! 
8 checked = in.readInt();! 
9 }! 
10 ! 
11 @Override! 
12 public void writeToParcel(Parcel out, int flags) {! 
13 super.writeToParcel(out, flags);! 
14 out.writeInt(checked);! 
15 }! 
16 ! 
17 public static final Parcelable.Creator<SavedState> CREATOR = ! 
18 new Parcelable.Creator<SavedState>() {! 
19 public SavedState createFromParcel(Parcel in) {! 
20 return new SavedState(in);! 
21 }! 
22 public SavedState[] newArray(int size) {! 
23 return new SavedState[size];! 
24 }! 
25 };! 
26 }
1 @Override! 
2 public Parcelable onSaveInstanceState() {! 
3 final Parcelable superState = super.onSaveInstanceState();! 
4 SavedState ss = new SavedState(superState);! 
5 ss.checked = isChecked() ? 1 : 0;! 
6 return ss;! 
7 }! 
8 ! 
9 @Override! 
10 public void onRestoreInstanceState(Parcelable state) {! 
11 SavedState ss = (SavedState) state;! 
12 super.onRestoreInstanceState(ss.getSuperState());! 
13 setChecked(ss.checked == 1);! 
14 }
FrameLayout! 
@id/root 
ImageBox! 
@id/container1 
CheckBox! 
@id/check_box 
ImageView! 
@id/image 
ImageBox! 
@id/container2 
CheckBox! 
@id/check_box 
ImageView! 
@id/image
FrameLayout! 
@id/root 
ImageBox! 
@id/container1 
ImageView! 
@id/image 
CheckBox! 
@id/check_box 
ImageBox! 
@id/container2 
ImageView! 
@id/image 
CheckBox! 
@id/check_box 
Custom views with children with same IDs
1 static class SavedState extends BaseSavedState {! 
2 ! 
3 SparseArray childrenStates;! 
4 ! 
5 SavedState(Parcelable superState) { super(superState); }! 
6 ! 
7 private SavedState(Parcel in, ClassLoader loader) {! 
8 super(in);! 
9 childrenStates = in.readSparseArray(loader);! 
10 }! 
11 ! 
12 @Override! 
13 public void writeToParcel(Parcel out, int flags) {! 
14 super.writeToParcel(out, flags);! 
15 out.writeSparseArray(childrenStates);! 
16 }! 
17 ! 
18 public static final Creator<SavedState> CREATOR = ParcelableCompat.! 
19 newCreator(new ParcelableCompatCreatorCallbacks<SavedState>() {! 
20 @Override! 
21 public SavedState createFromParcel(Parcel source, ClassLoader loader) {! 
22 return new SavedState(source, loader);! 
23 }! 
24 @Override! 
25 public SavedState[] newArray(int size) {! 
26 return new SavedState[size];! 
27 }! 
28 });! 
29 }
1 @Override! 
2 public Parcelable onSaveInstanceState() {! 
3 final Parcelable superState = super.onSaveInstanceState();! 
4 SavedState ss = new SavedState(superState);! 
5 ss.childrenStates = new SparseArray<Parcelable>();! 
6 for (int i = 0; i < getChildCount(); i++) {! 
7 getChildAt(i).saveHierarchyState(ss.childrenStates);! 
8 }! 
9 return ss;! 
10 }! 
11 ! 
12 @Override! 
13 public void onRestoreInstanceState(Parcelable state) {! 
14 SavedState ss = (SavedState) state;! 
15 super.onRestoreInstanceState(ss.getSuperState());! 
16 for (int i = 0; i < getChildCount(); i++) {! 
17 getChildAt(i).restoreHierarchyState(ss.childrenStates);! 
18 }! 
19 }
That has solved nothing! 
Still need to block save/restore dispatch
1 @Override! 
2 protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {! 
3 dispatchFreezeSelfOnly(container);! 
4 }! 
5 ! 
6 @Override! 
7 protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {! 
8 dispatchThawSelfOnly(container);! 
9 }
Fragment level 
state restoration
Very similar to Activities 
state restoration lifecycle. 
(Fragments are tied to Activity after all)
Fragment blocks Activity 
save mechanism 
with framework 
setSaveFromParentEnabled(false) 
with support library 
NoSaveStateFrameLayout
2 distinct states 
Fragment + View 
common case 
View only 
detach, addToBackStack, etc.
Leveraging save/restore 
Can to be used to create smooth transitions between 
your Activities: 
! 
- Save the state SA of A 
- Start B with no animations passing SA 
- Apply SA to B 
- Transition between A and B was smooth
Summarizing 
in three rules
Always save the state 
An Android app must survive configuration 
changes & low memory conditions.
Only save essential info 
Only save info that is non persistent 
or can not be reconstructed later.
Use correct levels 
Save instance states at the appropriate 
component level: Activity, Fragment or View.
Thank you! 
@cyrilmottier 
cyrilmottier.com
Resources 
Dressed for Iceland • Cécile Bernard 
Moelwynion, Eryri, Cymru • Marc Poppleton 
Happy, Confused, Wink, Sad, Angry • Megan Sheehan 
Floppy-Disk • Alex Auda Samora 
Fonts 
Source Sans Pro 
Courier

More Related Content

What's hot

JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven PractisesRobert MacLean
 
Vaadin 8 - Data Binding with Binder
Vaadin 8 - Data Binding with BinderVaadin 8 - Data Binding with Binder
Vaadin 8 - Data Binding with BinderPeter Lehto
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperGiordano Scalzo
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonFokke Zandbergen
 
GoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDGoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDBartłomiej Kiełbasa
 
Selectors and normalizing state shape
Selectors and normalizing state shapeSelectors and normalizing state shape
Selectors and normalizing state shapeMuntasir Chowdhury
 
Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Wilson Su
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to beJana Karceska
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11Michelangelo van Dam
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEDarwin Durand
 
Llibres pel curs 12-13
Llibres pel curs 12-13Llibres pel curs 12-13
Llibres pel curs 12-13toniarroyo9
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkKaniska Mandal
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF Luc Bors
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxMichelangelo van Dam
 
Let's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpecLet's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpecKenta Murata
 
The Ring programming language version 1.8 book - Part 119 of 202
The Ring programming language version 1.8 book - Part 119 of 202The Ring programming language version 1.8 book - Part 119 of 202
The Ring programming language version 1.8 book - Part 119 of 202Mahmoud Samir Fayed
 

What's hot (20)

JavaScript Proven Practises
JavaScript Proven PractisesJavaScript Proven Practises
JavaScript Proven Practises
 
Seam Glassfish Slidecast
Seam Glassfish SlidecastSeam Glassfish Slidecast
Seam Glassfish Slidecast
 
Vaadin 8 - Data Binding with Binder
Vaadin 8 - Data Binding with BinderVaadin 8 - Data Binding with Binder
Vaadin 8 - Data Binding with Binder
 
Tame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapperTame Accidental Complexity with Ruby and MongoMapper
Tame Accidental Complexity with Ruby and MongoMapper
 
Csb advertisment
Csb advertismentCsb advertisment
Csb advertisment
 
Alloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLonAlloy Tips & Tricks #TiLon
Alloy Tips & Tricks #TiLon
 
Library management system
Library management systemLibrary management system
Library management system
 
GoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDDGoCracow #5 Bartlomiej klimczak - GoBDD
GoCracow #5 Bartlomiej klimczak - GoBDD
 
Selectors and normalizing state shape
Selectors and normalizing state shapeSelectors and normalizing state shape
Selectors and normalizing state shape
 
Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8Practical JavaScript Programming - Session 8/8
Practical JavaScript Programming - Session 8/8
 
How Reactive do we need to be
How Reactive do we need to beHow Reactive do we need to be
How Reactive do we need to be
 
Unit testing with zend framework tek11
Unit testing with zend framework tek11Unit testing with zend framework tek11
Unit testing with zend framework tek11
 
Functions
FunctionsFunctions
Functions
 
VISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLEVISUALIZAR REGISTROS EN UN JTABLE
VISUALIZAR REGISTROS EN UN JTABLE
 
Llibres pel curs 12-13
Llibres pel curs 12-13Llibres pel curs 12-13
Llibres pel curs 12-13
 
Create a Customized GMF DnD Framework
Create a Customized GMF DnD FrameworkCreate a Customized GMF DnD Framework
Create a Customized GMF DnD Framework
 
How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF How to Bring Common UI Patterns to ADF
How to Bring Common UI Patterns to ADF
 
Unit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBeneluxUnit testing with zend framework PHPBenelux
Unit testing with zend framework PHPBenelux
 
Let's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpecLet's begin Behavior Driven Development using RSpec
Let's begin Behavior Driven Development using RSpec
 
The Ring programming language version 1.8 book - Part 119 of 202
The Ring programming language version 1.8 book - Part 119 of 202The Ring programming language version 1.8 book - Part 119 of 202
The Ring programming language version 1.8 book - Part 119 of 202
 

Viewers also liked

Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...Infinum
 
Smart Lock for Password @ Game DevFest Bangkok 2015
Smart Lock for Password @ Game DevFest Bangkok 2015Smart Lock for Password @ Game DevFest Bangkok 2015
Smart Lock for Password @ Game DevFest Bangkok 2015Somkiat Khitwongwattana
 
Android App Development - 07 Threading
Android App Development - 07 ThreadingAndroid App Development - 07 Threading
Android App Development - 07 ThreadingDiego Grancini
 
Android async task
Android async taskAndroid async task
Android async taskMadhu Venkat
 
Android Dialogs Tutorial
Android Dialogs TutorialAndroid Dialogs Tutorial
Android Dialogs TutorialPerfect APK
 
Android service, aidl - day 1
Android service, aidl - day 1Android service, aidl - day 1
Android service, aidl - day 1Utkarsh Mankad
 
Thread management
Thread management Thread management
Thread management Ayaan Adeel
 
Lecture Slides for Preferences and Menus [Android ]
Lecture Slides for Preferences and Menus [Android ]Lecture Slides for Preferences and Menus [Android ]
Lecture Slides for Preferences and Menus [Android ]Nehil Jain
 
Android intents, notification and broadcast recievers
Android intents, notification and broadcast recieversAndroid intents, notification and broadcast recievers
Android intents, notification and broadcast recieversUtkarsh Mankad
 
Android - Thread, Handler and AsyncTask
Android - Thread, Handler and AsyncTaskAndroid - Thread, Handler and AsyncTask
Android - Thread, Handler and AsyncTaskHoang Ngo
 
Android - Intents - Mazenet Solution
Android - Intents - Mazenet SolutionAndroid - Intents - Mazenet Solution
Android - Intents - Mazenet SolutionMazenetsolution
 

Viewers also liked (20)

Chapter 10 - Views Part 2
Chapter 10 - Views Part 2Chapter 10 - Views Part 2
Chapter 10 - Views Part 2
 
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
Infinum Android Talks #03 - Android Design Best Practices - for Designers and...
 
Smart Lock for Password @ Game DevFest Bangkok 2015
Smart Lock for Password @ Game DevFest Bangkok 2015Smart Lock for Password @ Game DevFest Bangkok 2015
Smart Lock for Password @ Game DevFest Bangkok 2015
 
Advanced iOS
Advanced iOSAdvanced iOS
Advanced iOS
 
Android App Development - 07 Threading
Android App Development - 07 ThreadingAndroid App Development - 07 Threading
Android App Development - 07 Threading
 
Android async task
Android async taskAndroid async task
Android async task
 
Android Dialogs Tutorial
Android Dialogs TutorialAndroid Dialogs Tutorial
Android Dialogs Tutorial
 
Android service, aidl - day 1
Android service, aidl - day 1Android service, aidl - day 1
Android service, aidl - day 1
 
Thread management
Thread management Thread management
Thread management
 
Advance Android Layout Walkthrough
Advance Android Layout WalkthroughAdvance Android Layout Walkthrough
Advance Android Layout Walkthrough
 
Lecture Slides for Preferences and Menus [Android ]
Lecture Slides for Preferences and Menus [Android ]Lecture Slides for Preferences and Menus [Android ]
Lecture Slides for Preferences and Menus [Android ]
 
Android service
Android serviceAndroid service
Android service
 
Android Threading
Android ThreadingAndroid Threading
Android Threading
 
AndroidManifest
AndroidManifestAndroidManifest
AndroidManifest
 
Android intents, notification and broadcast recievers
Android intents, notification and broadcast recieversAndroid intents, notification and broadcast recievers
Android intents, notification and broadcast recievers
 
NLP_lectures_English
NLP_lectures_EnglishNLP_lectures_English
NLP_lectures_English
 
Android - Thread, Handler and AsyncTask
Android - Thread, Handler and AsyncTaskAndroid - Thread, Handler and AsyncTask
Android - Thread, Handler and AsyncTask
 
Android intents
Android intentsAndroid intents
Android intents
 
Efficient Android Threading
Efficient Android ThreadingEfficient Android Threading
Efficient Android Threading
 
Android - Intents - Mazenet Solution
Android - Intents - Mazenet SolutionAndroid - Intents - Mazenet Solution
Android - Intents - Mazenet Solution
 

Similar to Deep dive into android restoration - DroidCon Paris 2014

¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?jaespinmora
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtextmeysholdt
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with ExtbaseJochen Rau
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector emberMatthew Beale
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Riza Fahmi
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptVisual Engineering
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceKonrad Malawski
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboardsDenis Ristic
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose worldFabio Collini
 
Soundreader.classpathSoundreader.project Soundre.docx
Soundreader.classpathSoundreader.project  Soundre.docxSoundreader.classpathSoundreader.project  Soundre.docx
Soundreader.classpathSoundreader.project Soundre.docxwhitneyleman54422
 
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Devon Bernard
 
Kotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKirill Rozov
 
Sharepoint Saturday India Online best practice for developing share point sol...
Sharepoint Saturday India Online best practice for developing share point sol...Sharepoint Saturday India Online best practice for developing share point sol...
Sharepoint Saturday India Online best practice for developing share point sol...Shakir Majeed Khan
 
Be More Productive with Kotlin
Be More Productive with KotlinBe More Productive with Kotlin
Be More Productive with KotlinBrandon Wever
 

Similar to Deep dive into android restoration - DroidCon Paris 2014 (20)

¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?¿Cómo de sexy puede hacer Backbone mi código?
¿Cómo de sexy puede hacer Backbone mi código?
 
Serializing EMF models with Xtext
Serializing EMF models with XtextSerializing EMF models with Xtext
Serializing EMF models with Xtext
 
Get into the FLOW with Extbase
Get into the FLOW with ExtbaseGet into the FLOW with Extbase
Get into the FLOW with Extbase
 
Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
 
Es.next
Es.nextEs.next
Es.next
 
Scalable vector ember
Scalable vector emberScalable vector ember
Scalable vector ember
 
Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6Essentials and Impactful Features of ES6
Essentials and Impactful Features of ES6
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016Evan Schultz - Angular Summit - 2016
Evan Schultz - Angular Summit - 2016
 
HBase RowKey design for Akka Persistence
HBase RowKey design for Akka PersistenceHBase RowKey design for Akka Persistence
HBase RowKey design for Akka Persistence
 
05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards05 JavaScript #burningkeyboards
05 JavaScript #burningkeyboards
 
Architectures in the compose world
Architectures in the compose worldArchitectures in the compose world
Architectures in the compose world
 
jQuery introduction
jQuery introductionjQuery introduction
jQuery introduction
 
Soundreader.classpathSoundreader.project Soundre.docx
Soundreader.classpathSoundreader.project  Soundre.docxSoundreader.classpathSoundreader.project  Soundre.docx
Soundreader.classpathSoundreader.project Soundre.docx
 
Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]Lean React - Patterns for High Performance [ploneconf2017]
Lean React - Patterns for High Performance [ploneconf2017]
 
Intro to ReactJS
Intro to ReactJSIntro to ReactJS
Intro to ReactJS
 
Kotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platformsKotlin 1.2: Sharing code between platforms
Kotlin 1.2: Sharing code between platforms
 
Sharepoint Saturday India Online best practice for developing share point sol...
Sharepoint Saturday India Online best practice for developing share point sol...Sharepoint Saturday India Online best practice for developing share point sol...
Sharepoint Saturday India Online best practice for developing share point sol...
 
Be More Productive with Kotlin
Be More Productive with KotlinBe More Productive with Kotlin
Be More Productive with Kotlin
 

More from Paris Android User Group

Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Paris Android User Group
 
Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Paris Android User Group
 
Extending your apps to wearables - DroidCon Paris 2014
Extending your apps to wearables -  DroidCon Paris 2014Extending your apps to wearables -  DroidCon Paris 2014
Extending your apps to wearables - DroidCon Paris 2014Paris Android User Group
 
Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Paris Android User Group
 
Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Paris Android User Group
 
Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Paris Android User Group
 
Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Paris Android User Group
 
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Paris Android User Group
 
maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014Paris Android User Group
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Paris Android User Group
 
Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Paris Android User Group
 
Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Paris Android User Group
 
Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Paris Android User Group
 
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Paris Android User Group
 
What's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseWhat's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseParis Android User Group
 
Efficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardEfficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardParis Android User Group
 

More from Paris Android User Group (20)

Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014Workshop: building your mobile backend with Parse - Droidcon Paris2014
Workshop: building your mobile backend with Parse - Droidcon Paris2014
 
Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014Workshop: Amazon developer ecosystem - DroidCon Paris2014
Workshop: Amazon developer ecosystem - DroidCon Paris2014
 
Extending your apps to wearables - DroidCon Paris 2014
Extending your apps to wearables -  DroidCon Paris 2014Extending your apps to wearables -  DroidCon Paris 2014
Extending your apps to wearables - DroidCon Paris 2014
 
Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014Scaling android development - DroidCon Paris 2014
Scaling android development - DroidCon Paris 2014
 
Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014Ingredient of awesome app - DroidCon Paris 2014
Ingredient of awesome app - DroidCon Paris 2014
 
Framing the canvas - DroidCon Paris 2014
Framing the canvas - DroidCon Paris 2014Framing the canvas - DroidCon Paris 2014
Framing the canvas - DroidCon Paris 2014
 
Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014Archos Android based connected home solution - DroidCon Paris 2014
Archos Android based connected home solution - DroidCon Paris 2014
 
Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014Porting VLC on Android - DroidCon Paris 2014
Porting VLC on Android - DroidCon Paris 2014
 
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
Robotium vs Espresso: Get ready to rumble ! - DroidCon Paris 2014
 
Buildsystem.mk - DroidCon Paris 2014
Buildsystem.mk - DroidCon Paris 2014Buildsystem.mk - DroidCon Paris 2014
Buildsystem.mk - DroidCon Paris 2014
 
maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014maximize app engagement and monetization - DroidCon Paris 2014
maximize app engagement and monetization - DroidCon Paris 2014
 
Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014Using the android ndk - DroidCon Paris 2014
Using the android ndk - DroidCon Paris 2014
 
Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014Holo material design transition - DroidCon Paris 2014
Holo material design transition - DroidCon Paris 2014
 
Death to passwords - DroidCon Paris 2014
Death to passwords - DroidCon Paris 2014Death to passwords - DroidCon Paris 2014
Death to passwords - DroidCon Paris 2014
 
Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014Google glass droidcon - DroidCon Paris 2014
Google glass droidcon - DroidCon Paris 2014
 
Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014Embedded webserver implementation and usage - DroidCon Paris 2014
Embedded webserver implementation and usage - DroidCon Paris 2014
 
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
Petit design Grande humanité par Geoffrey Dorne - DroidCon Paris 2014
 
What's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet HaaseWhat's new in android 4.4 - Romain Guy & Chet Haase
What's new in android 4.4 - Romain Guy & Chet Haase
 
Efficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas RoardEfficient Image Processing - Nicolas Roard
Efficient Image Processing - Nicolas Roard
 
Build a user experience by Eyal Lezmy
Build a user experience by Eyal LezmyBuild a user experience by Eyal Lezmy
Build a user experience by Eyal Lezmy
 

Recently uploaded

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr LapshynFwdays
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 

Recently uploaded (20)

Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
"Federated learning: out of reach no matter how close",Oleksandr Lapshyn
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 

Deep dive into android restoration - DroidCon Paris 2014

  • 1. Deep Dive Into Android State Restoration
  • 2. TWITTER @cyrilmottier ! WEBSITE cyrilmottier.com
  • 3.
  • 4.
  • 5.
  • 6.
  • 7. The story of a newbie Android developer
  • 8. Kevin has just developed his first Android app
  • 9. He discovers an annoying bug: Fields are cleared on rotate
  • 12. 3 options Don’t care Block orientation
  • 13. 3 options Don’t care Block orientation Use configChanges Hint: all options are
  • 14. 1 <activity! 2 android:name=".HomeActivity"! 3 android:configChanges="orientation">! 4 ! 5 <!-- Some sweet IntentFilters. -->! 6 ! 7 </activity>
  • 17. Still having issues on… language changes
  • 18. 1 <activity! 2 android:name=".HomeActivity"! 3 android:configChanges="orientation! 4 ! 5 <!-- Some annoying IntentFilters. -->! 6 ! 7 </activity> |locale">
  • 20. 1 <activity! 2 android:name=".HomeActivity"! 3 android:configChanges=“orientation|locale|! mcc|mnc|touchscreen|keyboard|! keyboardHidden|navigation|uiMode|! screenLayout|fontScale|screenSize|! smallestScreenSize">! 4 ! 5 <!-- Some fuc**** IntentFilters. Arrggh! -->! 6 ! 7 </activity>
  • 21. The nightmare continues… Still having issues when moving the app to the background
  • 22. God save the STATE
  • 23. State restoration key components
  • 25. The container Parcel The content Primitives types Primitives arrays Parcelable
  • 26. The content Primitives types Primitives arrays 1 parcel.writeInt(1);! 2 parcel.writeLong(2L);! 3 parcel.writeFloat(3F);! 4 parcel.writeString("Hi!"); Parcelable
  • 27. 1 parcel.writeIntArray(new int[]{1, 2, 3});! 2 parcel.writeLongArray(new long[]{1L, 2L, 3L});! 3 parcel.writeDoubleArray(new double[]{1, 2, 3});! 4 parcel.writeStringArray(new String[]{! 5 "Hi", "Droidcon", "guys!"! 6 }); The content Primitives types Primitives arrays Parcelable
  • 28. 1 public final class Suggestion implements Parcelable {! 2 ! 3 public final String id;! 4 public final String name;! 5 public final int type;! 6 ! 7 public Suggestion(String id, String name, int type) {! 8 this.id = Objects.requireNonNull(id);! 9 this.name = Objects.requireNonNull(name);! 10 this.type = type;! 11 }! 12 ! 13 }
  • 29. 1 @Override! 2 public int describeContents() {! 3 return 0;! 4 }! 5 ! 6 @Override! 7 public void writeToParcel(Parcel dest, int flags) {! 8 dest.writeString(id);! 9 dest.writeString(name);! 10 dest.writeInt(type);! 11 }! 12 13 public static final Parcelable.Creator<Suggestion> CREATOR = ! 14 new Parcelable.Creator<Suggestion>() {! 15 public Suggestion createFromParcel(Parcel in) {! 16 return new Suggestion(in.readString(), // ! 17 in.readString(), //! 18 in.readInt());! 19 }! 20 ! 21 public Suggestion[] newArray(int size) {! 22 return new Suggestion[size];! 23 }! 24 };
  • 30. Parcelable.Creator! The base creator interface ! Parcelable.ClassLoaderCreator! A creator with the ClassLoader passed on read. ! ParcelableCompat & ParcelableCompatCreatorCallbacks! Compatibility stuff
  • 31. Bundle A key-value map & type-safe Parcelable
  • 32. Parcel! internally uses reflection (required to get the CREATOR instance) …i.e. beware Proguard
  • 33. Activity level state restoration
  • 36. : non-null Bundle onCreate(null) onSaveInstanceState( )
  • 37. onCreate(null) onSaveInstanceState( ) onCreate( ) : non-null Bundle
  • 38. onCreate(null) onSaveInstanceState( ) onCreate( ) onRestoreInstanceState( ) : non-null Bundle
  • 39. onCreate(null) onSaveInstanceState( ) onCreate( ) onRestoreInstanceState( ) : non-null Bundle
  • 40. onCreate(null) onSaveInstanceState( ) onCreate( ) onRestoreInstanceState( ) : non-null Bundle
  • 41. What to save? Non persistent or non reconstructible info
  • 42. 1 public class SearchActivity extends Activity {! 2 ! 3 private static final String STATE_OUTWARD = "state:outward";! 4 ! 5 private DateComponents mOutward;! 6 ! 7 @Override! 8 protected void onCreate(Bundle inState) {! 9 super.onCreate(inState);! 10 ! 11 if (inState != null) {! 12 DateComponents components = inState.getParcelable(STATE_OUTWARD);! 13 if (components != null) {! 14 setOutward(components);! 15 }! 16 }! 17 }! 18 ! 19 @Override! 20 protected void onSaveInstanceState(Bundle outState) {! 21 super.onSaveInstanceState(outState);! 22 outState.putParcelable(STATE_OUTWARD, mOutward);! 23 }! 24 }
  • 45. onSaveInstanceState saves Window Fragments Dialogs
  • 46. Always call the SUPER METHODS Android has no guards on save-related methods
  • 47. android:stateNotNeeded For restart-on-crash apps only (i.e. launcher app)
  • 48. Developer options Don’t keep activities
  • 49. Developer options Don’t keep activities
  • 50. View level state restoration
  • 51. Android saves UI state AUTOMAGICALLY
  • 52. Android saves UI state AUTOMAGICALLY (aka “It just works!™”)
  • 53. Android saves UI state AUTOMAGICALLY (aka “It just works!™”) …except in some cases
  • 54. Works out-of-the-box if Views 1. Have an ID 2. Are “save” enabled 3. Come from the framework
  • 55. It always begins with a call to saveHierarchyState()
  • 56. EditText! @id/text RelativeLayout! @id/container TextView CheckBox! @id/check_box
  • 57. EditText! @id/text RelativeLayout! @id/container TextView CheckBox! @id/check_box SparseArray<Parcelable>
  • 58. RelativeLayout! @id/container TextView CheckBox! @id/check_box SparseArray<Parcelable> S1 EditText! @id/text
  • 59. SparseArray<Parcelable> @id/container RelativeLayout! @id/container TextView CheckBox! @id/check_box S1 EditText! @id/text
  • 60. EditText! @id/text RelativeLayout! @id/container TextView CheckBox! @id/check_box S2 SparseArray<Parcelable> @id/container S1
  • 61. SparseArray<Parcelable> @id/container S1 @id/text S2 RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 62. RelativeLayout! @id/container TextView CheckBox! @id/check_box SparseArray<Parcelable> @id/container S1 @id/text S2 S3 EditText! @id/text
  • 63. SparseArray<Parcelable> @id/container @id/text @id/check_box S1 S2 S3 RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 64. Controlling save setSaveEnabled(boolean) setSaveFromParentEnabled(boolean)
  • 65. It always ends with a call to restoreHierarchyState()
  • 66. SparseArray<Parcelable> @id/container S1 @id/text S2 @id/check_box S3 RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 67. SparseArray<Parcelable> @id/container S1 S2 S3 @id/text @id/check_box RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 68. RelativeLayout! @id/container TextView CheckBox! @id/check_box SparseArray<Parcelable> @id/container S1 S2 @id/check_box S3 S1 @id/text EditText! @id/text
  • 69. SparseArray<Parcelable> @id/container S1 @id/text S2 @id/check_box S3 RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 70. EditText! @id/text RelativeLayout! @id/container TextView CheckBox! @id/check_box S2 SparseArray<Parcelable> @id/container S1 @id/text S2 @id/check_box S3
  • 71. SparseArray<Parcelable> @id/container S1 @id/text S2 @id/check_box S3 RelativeLayout! @id/container EditText! @id/text TextView CheckBox! @id/check_box
  • 72. RelativeLayout! @id/container TextView CheckBox! @id/check_box @id/container S1 @id/text S2 @id/check_box S3 S3 SparseArray<Parcelable> EditText! @id/text
  • 73. Ensure your Views’ IDs are unique & constant
  • 74. 1 static class SavedState extends BaseSavedState {! 2 int checked;! 3 ! 4 SavedState(Parcelable superState) { super(superState); }! 5 ! 6 private SavedState(Parcel in) {! 7 super(in);! 8 checked = in.readInt();! 9 }! 10 ! 11 @Override! 12 public void writeToParcel(Parcel out, int flags) {! 13 super.writeToParcel(out, flags);! 14 out.writeInt(checked);! 15 }! 16 ! 17 public static final Parcelable.Creator<SavedState> CREATOR = ! 18 new Parcelable.Creator<SavedState>() {! 19 public SavedState createFromParcel(Parcel in) {! 20 return new SavedState(in);! 21 }! 22 public SavedState[] newArray(int size) {! 23 return new SavedState[size];! 24 }! 25 };! 26 }
  • 75. 1 @Override! 2 public Parcelable onSaveInstanceState() {! 3 final Parcelable superState = super.onSaveInstanceState();! 4 SavedState ss = new SavedState(superState);! 5 ss.checked = isChecked() ? 1 : 0;! 6 return ss;! 7 }! 8 ! 9 @Override! 10 public void onRestoreInstanceState(Parcelable state) {! 11 SavedState ss = (SavedState) state;! 12 super.onRestoreInstanceState(ss.getSuperState());! 13 setChecked(ss.checked == 1);! 14 }
  • 76. FrameLayout! @id/root ImageBox! @id/container1 CheckBox! @id/check_box ImageView! @id/image ImageBox! @id/container2 CheckBox! @id/check_box ImageView! @id/image
  • 77. FrameLayout! @id/root ImageBox! @id/container1 ImageView! @id/image CheckBox! @id/check_box ImageBox! @id/container2 ImageView! @id/image CheckBox! @id/check_box Custom views with children with same IDs
  • 78. 1 static class SavedState extends BaseSavedState {! 2 ! 3 SparseArray childrenStates;! 4 ! 5 SavedState(Parcelable superState) { super(superState); }! 6 ! 7 private SavedState(Parcel in, ClassLoader loader) {! 8 super(in);! 9 childrenStates = in.readSparseArray(loader);! 10 }! 11 ! 12 @Override! 13 public void writeToParcel(Parcel out, int flags) {! 14 super.writeToParcel(out, flags);! 15 out.writeSparseArray(childrenStates);! 16 }! 17 ! 18 public static final Creator<SavedState> CREATOR = ParcelableCompat.! 19 newCreator(new ParcelableCompatCreatorCallbacks<SavedState>() {! 20 @Override! 21 public SavedState createFromParcel(Parcel source, ClassLoader loader) {! 22 return new SavedState(source, loader);! 23 }! 24 @Override! 25 public SavedState[] newArray(int size) {! 26 return new SavedState[size];! 27 }! 28 });! 29 }
  • 79. 1 @Override! 2 public Parcelable onSaveInstanceState() {! 3 final Parcelable superState = super.onSaveInstanceState();! 4 SavedState ss = new SavedState(superState);! 5 ss.childrenStates = new SparseArray<Parcelable>();! 6 for (int i = 0; i < getChildCount(); i++) {! 7 getChildAt(i).saveHierarchyState(ss.childrenStates);! 8 }! 9 return ss;! 10 }! 11 ! 12 @Override! 13 public void onRestoreInstanceState(Parcelable state) {! 14 SavedState ss = (SavedState) state;! 15 super.onRestoreInstanceState(ss.getSuperState());! 16 for (int i = 0; i < getChildCount(); i++) {! 17 getChildAt(i).restoreHierarchyState(ss.childrenStates);! 18 }! 19 }
  • 80. That has solved nothing! Still need to block save/restore dispatch
  • 81. 1 @Override! 2 protected void dispatchSaveInstanceState(SparseArray<Parcelable> container) {! 3 dispatchFreezeSelfOnly(container);! 4 }! 5 ! 6 @Override! 7 protected void dispatchRestoreInstanceState(SparseArray<Parcelable> container) {! 8 dispatchThawSelfOnly(container);! 9 }
  • 82. Fragment level state restoration
  • 83. Very similar to Activities state restoration lifecycle. (Fragments are tied to Activity after all)
  • 84. Fragment blocks Activity save mechanism with framework setSaveFromParentEnabled(false) with support library NoSaveStateFrameLayout
  • 85. 2 distinct states Fragment + View common case View only detach, addToBackStack, etc.
  • 86. Leveraging save/restore Can to be used to create smooth transitions between your Activities: ! - Save the state SA of A - Start B with no animations passing SA - Apply SA to B - Transition between A and B was smooth
  • 88. Always save the state An Android app must survive configuration changes & low memory conditions.
  • 89. Only save essential info Only save info that is non persistent or can not be reconstructed later.
  • 90. Use correct levels Save instance states at the appropriate component level: Activity, Fragment or View.
  • 91. Thank you! @cyrilmottier cyrilmottier.com
  • 92. Resources Dressed for Iceland • Cécile Bernard Moelwynion, Eryri, Cymru • Marc Poppleton Happy, Confused, Wink, Sad, Angry • Megan Sheehan Floppy-Disk • Alex Auda Samora Fonts Source Sans Pro Courier