SlideShare ist ein Scribd-Unternehmen logo
1 von 48
Downloaden Sie, um offline zu lesen
Staying alive
Online and offline
Erik Hellman, BonTouch
@ErikHellman
How well does your app
work offline?
When leaving my apartment
Why?
4 Reduce glitches
4 Roaming users
4 Missing coverage
4 Improve performance
4 Reduce data costs
Offline examples
How?
4 Connectivity detection
4 Request queing
4 Caching
4 Preloading
Challenges
4 Captive Portals
4 Network handover
4 Temporary network loss
4 Timeouts
4 2G Voice and Data
4 Local Storage
4 Request Serialization
4 ...and more
Detecting connectivity
boolean isNetworkAvailable() {
ConnectivityManager mgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = mgr.getActiveNetworkInfo();
return networkInfo != null && networkInfo.isConnected();
}
4 Checks network state right now
4 Captive portals detection (since API level 17)
4 Poor networks (since API level 16)
4 Must be called before every network operation
4 Will indicate DISCONNECTED if background data is disabled!
Listen for changes
private void setupNetworkChangeListener() {
IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
this.networkStateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager mgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = mgr.getActiveNetworkInfo();
notifyNetworkState(networkInfo != null && networkInfo.isConnected());
}
};
registerReceiver(networkStateReceiver, intentFilter);
}
4 Continously listen for network state changes
4 Remember to unregister!
NetworkInfo.State
public enum State {
CONNECTING,
CONNECTED,
SUSPENDED,
DISCONNECTING,
DISCONNECTED,
UNKNOWN
}
NetworkInfo.DetailedState
public enum DetailedState {
IDLE,
SCANNING,
CONNECTING,
AUTHENTICATING,
OBTAINING_IPADDR,
CONNECTED,
SUSPENDED,
DISCONNECTING,
DISCONNECTED,
FAILED,
BLOCKED,
VERIFYING_POOR_LINK,
CAPTIVE_PORTAL_CHECK
}
private static final EnumMap<DetailedState, State> stateMap =
new EnumMap<DetailedState, State>(DetailedState.class);
static {
stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
}
Unexpected conditions
4 2G Voice and Data
4 Flight Mode
public static boolean isAirplaneModeOn(Context context) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
return Settings.System.getInt(context.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) != 0;
} else {
return Settings.Global.getInt(context.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
15 minutes
socket timeout
Response Times:
The 3 Important Limits
4 0.1 seconds - system is reacting instantaneously
4 1.0 seconds - limit for user's flow of thought to stay uninterrupted
4 10 seconds - limit for keeping the user's attention
...response time guidelines for web-based applications are the same as for all
other applications...
— Jakob Nielsen, http://www.nngroup.com/articles/response-times-3-
important-limits/
Timeout for HttpURLConnection
URL url = new URL(url);
HttpURLConnection urlConnection = url.openConnection();
urlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
Timeout for OkHttpClient
OkHttpClient client = new OkHttpClient();
client.setConnectTimeout(CONNECTION_TIMEOUT);
client.setReadTimeout(CONNECTION_TIMEOUT);
Request Serialzation
Queing outgoing requests
// In your Activity
startService(buildRequestIntent(url, data));
// IntentService.onHandleIntent()
is(isConnected(this)) {
performRequest(url, data);
} else {
serializeRequest(url, data);
}
// BroadcastReceiver listening for network changes
if(isConnected(context)) {
context.startService(new Intent(ACTION_SEND_QUEUED_REQUESTS));
}
Alternatives
4 Firebase
4 Couchebase
Request serialization
4 Query params?
4 Request body?
4 HTTP headers?
4 Timestamp?
Request serialization
public void serializeRequest(url, data) {
ContentValues values = new ContentValues();
values.put("url", url);
values.put("data", data);
getContentResolver.insert(...);
}
Caching
4 Not HTTP Response cache!
4 Custom cache implementations
4 Don't evict when offline?
4 Context.getCacheDir(), Context.getFilesDir() or
Context.getExternalFilesDir()?
Caching examples
DiskLruCache.java
Load from cache or network?
// Our sources (left as an exercise for the reader)
Observable<Data> memory = ...;
Observable<Data> disk = ...;
Observable<Data> network = ...;
// Retrieve the first source with data
Observable<Data> source = Observable
.concat(memory, disk, network)
.first();
4 Dan Lew, http://blog.danlew.net/2015/06/22/loading-data-from-
multiple-sources-with-rxjava/
Preload data for offline
4 Assets or Raw resources (100 MB)
4 APK Expansion files (2 * 2GB)
4 Download at first startup (unlimited)
How much data?
Street addresses
4 Sweden: 650 000 ~ 7 MB
4 US: 154 million ~ 1.6 GB
Preloading SQLite DB
private SQLiteDatabase openPreloadedSQLiteDB() {
File localCopy = new File(getFilesDir(), DB_NAME);
if (localCopy.exists()) { // TODO Perform version check!
InputStream inputStream = getResources().openRawResource(R.raw.preloaded_db);
readStreamToFile(inputStream, localCopy);
}
return SQLiteDatabase.openOrCreateDatabase(localCopy, null);
}
Local storage
4 Micromax Canvas A1 (Android One) - 2GB internal
storage
4 Use external storage
public static void saveFileToExternalStorage(Context context, String filename, byte[] data) {
File appPrivateFile = new File(context.getExternalFilesDir(null), filename);
writeBytesToFile(data, appPrivateFile);
}
Mesh networking?
4 Bluetooth
4 WiFi Direct
Conclusions
Don't ignore offline!
Thanks for listening!
@ErikHellman

Weitere ähnliche Inhalte

Was ist angesagt?

DOM-based Test Adequacy Criteria for Web Applications
DOM-based Test Adequacy Criteria for Web ApplicationsDOM-based Test Adequacy Criteria for Web Applications
DOM-based Test Adequacy Criteria for Web Applications
SALT Lab @ UBC
 
Understanding JavaScript Event-based Interactions
Understanding JavaScript Event-based InteractionsUnderstanding JavaScript Event-based Interactions
Understanding JavaScript Event-based Interactions
SALT Lab @ UBC
 
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache FlinkMaximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Flink Forward
 
Hidden-Web Induced by Client-Side Scripting: An Empirical Study
Hidden-Web Induced by Client-Side Scripting: An Empirical StudyHidden-Web Induced by Client-Side Scripting: An Empirical Study
Hidden-Web Induced by Client-Side Scripting: An Empirical Study
SALT Lab @ UBC
 

Was ist angesagt? (20)

Data Collection & Prometheus Scraping with Sensu 2.0
Data Collection & Prometheus Scraping with Sensu 2.0Data Collection & Prometheus Scraping with Sensu 2.0
Data Collection & Prometheus Scraping with Sensu 2.0
 
TPL Dataflow – зачем и для кого?
TPL Dataflow – зачем и для кого?TPL Dataflow – зачем и для кого?
TPL Dataflow – зачем и для кого?
 
What i got wrong when somebody asked me to deploy a web app
What i got wrong when somebody asked me to deploy a web appWhat i got wrong when somebody asked me to deploy a web app
What i got wrong when somebody asked me to deploy a web app
 
A Call for Sanity in NoSQL
A Call for Sanity in NoSQLA Call for Sanity in NoSQL
A Call for Sanity in NoSQL
 
DOM-based Test Adequacy Criteria for Web Applications
DOM-based Test Adequacy Criteria for Web ApplicationsDOM-based Test Adequacy Criteria for Web Applications
DOM-based Test Adequacy Criteria for Web Applications
 
Understanding JavaScript Event-based Interactions
Understanding JavaScript Event-based InteractionsUnderstanding JavaScript Event-based Interactions
Understanding JavaScript Event-based Interactions
 
Web
WebWeb
Web
 
Tpl dataflow
Tpl dataflowTpl dataflow
Tpl dataflow
 
2310 b 12
2310 b 122310 b 12
2310 b 12
 
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache FlinkMaximilian Michels – Google Cloud Dataflow on Top of Apache Flink
Maximilian Michels – Google Cloud Dataflow on Top of Apache Flink
 
Webinar slides "Building Real-Time Collaborative Web Applications"
Webinar slides "Building Real-Time Collaborative Web Applications"Webinar slides "Building Real-Time Collaborative Web Applications"
Webinar slides "Building Real-Time Collaborative Web Applications"
 
Jupyter Notebooks for machine learning on Kubernetes & OpenShift | DevNation ...
Jupyter Notebooks for machine learning on Kubernetes & OpenShift | DevNation ...Jupyter Notebooks for machine learning on Kubernetes & OpenShift | DevNation ...
Jupyter Notebooks for machine learning on Kubernetes & OpenShift | DevNation ...
 
Hidden-Web Induced by Client-Side Scripting: An Empirical Study
Hidden-Web Induced by Client-Side Scripting: An Empirical StudyHidden-Web Induced by Client-Side Scripting: An Empirical Study
Hidden-Web Induced by Client-Side Scripting: An Empirical Study
 
Monitoring using Prometheus and Grafana
Monitoring using Prometheus and GrafanaMonitoring using Prometheus and Grafana
Monitoring using Prometheus and Grafana
 
Reactive Spring 5
Reactive Spring 5Reactive Spring 5
Reactive Spring 5
 
Autodiscover flow in an exchange on premises environment non-active director...
Autodiscover flow in an exchange on premises environment  non-active director...Autodiscover flow in an exchange on premises environment  non-active director...
Autodiscover flow in an exchange on premises environment non-active director...
 
Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5Reactive Programming in Java and Spring Framework 5
Reactive Programming in Java and Spring Framework 5
 
Microservices for Systematic Profiling and Monitoring of the Refactoring
Microservices for Systematic Profiling and Monitoring of the RefactoringMicroservices for Systematic Profiling and Monitoring of the Refactoring
Microservices for Systematic Profiling and Monitoring of the Refactoring
 
Big Data Warsaw
Big Data WarsawBig Data Warsaw
Big Data Warsaw
 
Packet filtering using jpcap
Packet filtering using jpcapPacket filtering using jpcap
Packet filtering using jpcap
 

Andere mochten auch

Andere mochten auch (13)

Brand Insights with Ripl
Brand Insights with RiplBrand Insights with Ripl
Brand Insights with Ripl
 
Plan Book Final
Plan Book FinalPlan Book Final
Plan Book Final
 
Spencer stuart, Multifamily Development Today
Spencer stuart, Multifamily Development TodaySpencer stuart, Multifamily Development Today
Spencer stuart, Multifamily Development Today
 
America's Next Top Multifamily Marketer
America's Next Top Multifamily MarketerAmerica's Next Top Multifamily Marketer
America's Next Top Multifamily Marketer
 
TPA - The Bluffs
TPA - The BluffsTPA - The Bluffs
TPA - The Bluffs
 
Apartment Hunting: “The Social Experience”, Chris Vaughn, Apartment Finder, D...
Apartment Hunting: “The Social Experience”, Chris Vaughn, Apartment Finder, D...Apartment Hunting: “The Social Experience”, Chris Vaughn, Apartment Finder, D...
Apartment Hunting: “The Social Experience”, Chris Vaughn, Apartment Finder, D...
 
Integrating Social Media Into an Overall Marketing Strategy
Integrating Social Media Into an Overall Marketing StrategyIntegrating Social Media Into an Overall Marketing Strategy
Integrating Social Media Into an Overall Marketing Strategy
 
Virtual staging for apartments
Virtual staging for apartments Virtual staging for apartments
Virtual staging for apartments
 
Online marketing and advertising for the Apartment Industry
Online marketing and advertising for the Apartment IndustryOnline marketing and advertising for the Apartment Industry
Online marketing and advertising for the Apartment Industry
 
Marketing for the Moments That Matter Most for Apartment Shoppers
Marketing for the Moments That Matter Most for Apartment ShoppersMarketing for the Moments That Matter Most for Apartment Shoppers
Marketing for the Moments That Matter Most for Apartment Shoppers
 
Oklahoma
OklahomaOklahoma
Oklahoma
 
Bricktown Final February
Bricktown Final FebruaryBricktown Final February
Bricktown Final February
 
Reno Multifamily Report - 2016 Year End & Q416
Reno Multifamily Report - 2016 Year End & Q416Reno Multifamily Report - 2016 Year End & Q416
Reno Multifamily Report - 2016 Year End & Q416
 

Ähnlich wie Statying Alive - Online and OFfline

Connecting to the network
Connecting to the networkConnecting to the network
Connecting to the network
Mu Chun Wang
 

Ähnlich wie Statying Alive - Online and OFfline (20)

Performance #4 network
Performance #4  networkPerformance #4  network
Performance #4 network
 
Solving anything in VCL
Solving anything in VCLSolving anything in VCL
Solving anything in VCL
 
Android Performance #4: Network
Android Performance #4: NetworkAndroid Performance #4: Network
Android Performance #4: Network
 
Connecting to the network
Connecting to the networkConnecting to the network
Connecting to the network
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of users
 
Scaling application with RabbitMQ
Scaling application with RabbitMQScaling application with RabbitMQ
Scaling application with RabbitMQ
 
Android Networking
Android NetworkingAndroid Networking
Android Networking
 
Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)Sherlock Homepage (Maarten Balliauw)
Sherlock Homepage (Maarten Balliauw)
 
Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...Sherlock Homepage - A detective story about running large web services (VISUG...
Sherlock Homepage - A detective story about running large web services (VISUG...
 
Go 1.8 'new' networking features
Go 1.8 'new' networking featuresGo 1.8 'new' networking features
Go 1.8 'new' networking features
 
Android Networking
Android NetworkingAndroid Networking
Android Networking
 
Oracle High Availabiltity for application developers
Oracle High Availabiltity for application developersOracle High Availabiltity for application developers
Oracle High Availabiltity for application developers
 
Middleware webnextconf - 20152609
Middleware   webnextconf - 20152609Middleware   webnextconf - 20152609
Middleware webnextconf - 20152609
 
Sherlock Homepage - A detective story about running large web services - NDC ...
Sherlock Homepage - A detective story about running large web services - NDC ...Sherlock Homepage - A detective story about running large web services - NDC ...
Sherlock Homepage - A detective story about running large web services - NDC ...
 
Lecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile DevicesLecture 10 Networking on Mobile Devices
Lecture 10 Networking on Mobile Devices
 
TDC2016SP - Vamos falar sobre o futuro da web: HTTP/2
TDC2016SP - Vamos falar sobre o futuro da web: HTTP/2TDC2016SP - Vamos falar sobre o futuro da web: HTTP/2
TDC2016SP - Vamos falar sobre o futuro da web: HTTP/2
 
Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019Rethinking Syncing at AltConf 2019
Rethinking Syncing at AltConf 2019
 
Apache httpd reverse proxy and Tomcat
Apache httpd reverse proxy and TomcatApache httpd reverse proxy and Tomcat
Apache httpd reverse proxy and Tomcat
 
Android rest client applications-services approach @Droidcon Bucharest 2012
Android rest client applications-services approach @Droidcon Bucharest 2012Android rest client applications-services approach @Droidcon Bucharest 2012
Android rest client applications-services approach @Droidcon Bucharest 2012
 
Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...Sherlock Homepage - A detective story about running large web services - WebN...
Sherlock Homepage - A detective story about running large web services - WebN...
 

Kürzlich hochgeladen

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Cara Menggugurkan Kandungan 087776558899
 

Kürzlich hochgeladen (6)

Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
Obat Penggugur Kandungan Di Apotik Kimia Farma (087776558899)
 
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost LoverPowerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
Powerful Love Spells in Arkansas, AR (310) 882-6330 Bring Back Lost Lover
 
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort ServiceBDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
BDSM⚡Call Girls in Sector 71 Noida Escorts >༒8448380779 Escort Service
 
Leading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdfLeading Mobile App Development Companies in India (2).pdf
Leading Mobile App Development Companies in India (2).pdf
 
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
9999266834 Call Girls In Noida Sector 52 (Delhi) Call Girl Service
 
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCRFULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
FULL ENJOY - 9999218229 Call Girls in {Mahipalpur}| Delhi NCR
 

Statying Alive - Online and OFfline

  • 1. Staying alive Online and offline Erik Hellman, BonTouch @ErikHellman
  • 2. How well does your app work offline?
  • 3. When leaving my apartment
  • 4.
  • 5.
  • 6. Why? 4 Reduce glitches 4 Roaming users 4 Missing coverage 4 Improve performance 4 Reduce data costs
  • 8.
  • 9.
  • 10.
  • 11.
  • 12. How? 4 Connectivity detection 4 Request queing 4 Caching 4 Preloading
  • 13. Challenges 4 Captive Portals 4 Network handover 4 Temporary network loss 4 Timeouts 4 2G Voice and Data 4 Local Storage 4 Request Serialization 4 ...and more
  • 14. Detecting connectivity boolean isNetworkAvailable() { ConnectivityManager mgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = mgr.getActiveNetworkInfo(); return networkInfo != null && networkInfo.isConnected(); } 4 Checks network state right now 4 Captive portals detection (since API level 17) 4 Poor networks (since API level 16) 4 Must be called before every network operation 4 Will indicate DISCONNECTED if background data is disabled!
  • 15. Listen for changes private void setupNetworkChangeListener() { IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION); this.networkStateReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { ConnectivityManager mgr = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkInfo networkInfo = mgr.getActiveNetworkInfo(); notifyNetworkState(networkInfo != null && networkInfo.isConnected()); } }; registerReceiver(networkStateReceiver, intentFilter); } 4 Continously listen for network state changes 4 Remember to unregister!
  • 16. NetworkInfo.State public enum State { CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN }
  • 17. NetworkInfo.DetailedState public enum DetailedState { IDLE, SCANNING, CONNECTING, AUTHENTICATING, OBTAINING_IPADDR, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, FAILED, BLOCKED, VERIFYING_POOR_LINK, CAPTIVE_PORTAL_CHECK }
  • 18. private static final EnumMap<DetailedState, State> stateMap = new EnumMap<DetailedState, State>(DetailedState.class); static { stateMap.put(DetailedState.IDLE, State.DISCONNECTED); stateMap.put(DetailedState.SCANNING, State.DISCONNECTED); stateMap.put(DetailedState.CONNECTING, State.CONNECTING); stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING); stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING); stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING); stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING); stateMap.put(DetailedState.CONNECTED, State.CONNECTED); stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED); stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING); stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED); stateMap.put(DetailedState.FAILED, State.DISCONNECTED); stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED); }
  • 19. Unexpected conditions 4 2G Voice and Data 4 Flight Mode public static boolean isAirplaneModeOn(Context context) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { return Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; } else { return Settings.Global.getInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) != 0; } }
  • 20.
  • 21.
  • 22.
  • 24. Response Times: The 3 Important Limits 4 0.1 seconds - system is reacting instantaneously 4 1.0 seconds - limit for user's flow of thought to stay uninterrupted 4 10 seconds - limit for keeping the user's attention ...response time guidelines for web-based applications are the same as for all other applications... — Jakob Nielsen, http://www.nngroup.com/articles/response-times-3- important-limits/
  • 25. Timeout for HttpURLConnection URL url = new URL(url); HttpURLConnection urlConnection = url.openConnection(); urlConnection.setConnectTimeout(CONNECTION_TIMEOUT); urlConnection.setReadTimeout(CONNECTION_TIMEOUT);
  • 26. Timeout for OkHttpClient OkHttpClient client = new OkHttpClient(); client.setConnectTimeout(CONNECTION_TIMEOUT); client.setReadTimeout(CONNECTION_TIMEOUT);
  • 28.
  • 29.
  • 30. Queing outgoing requests // In your Activity startService(buildRequestIntent(url, data)); // IntentService.onHandleIntent() is(isConnected(this)) { performRequest(url, data); } else { serializeRequest(url, data); } // BroadcastReceiver listening for network changes if(isConnected(context)) { context.startService(new Intent(ACTION_SEND_QUEUED_REQUESTS)); }
  • 32. Request serialization 4 Query params? 4 Request body? 4 HTTP headers? 4 Timestamp?
  • 33. Request serialization public void serializeRequest(url, data) { ContentValues values = new ContentValues(); values.put("url", url); values.put("data", data); getContentResolver.insert(...); }
  • 34. Caching 4 Not HTTP Response cache! 4 Custom cache implementations 4 Don't evict when offline? 4 Context.getCacheDir(), Context.getFilesDir() or Context.getExternalFilesDir()?
  • 36.
  • 37.
  • 38.
  • 39.
  • 41. Load from cache or network? // Our sources (left as an exercise for the reader) Observable<Data> memory = ...; Observable<Data> disk = ...; Observable<Data> network = ...; // Retrieve the first source with data Observable<Data> source = Observable .concat(memory, disk, network) .first(); 4 Dan Lew, http://blog.danlew.net/2015/06/22/loading-data-from- multiple-sources-with-rxjava/
  • 42. Preload data for offline 4 Assets or Raw resources (100 MB) 4 APK Expansion files (2 * 2GB) 4 Download at first startup (unlimited)
  • 43. How much data? Street addresses 4 Sweden: 650 000 ~ 7 MB 4 US: 154 million ~ 1.6 GB
  • 44. Preloading SQLite DB private SQLiteDatabase openPreloadedSQLiteDB() { File localCopy = new File(getFilesDir(), DB_NAME); if (localCopy.exists()) { // TODO Perform version check! InputStream inputStream = getResources().openRawResource(R.raw.preloaded_db); readStreamToFile(inputStream, localCopy); } return SQLiteDatabase.openOrCreateDatabase(localCopy, null); }
  • 45. Local storage 4 Micromax Canvas A1 (Android One) - 2GB internal storage 4 Use external storage public static void saveFileToExternalStorage(Context context, String filename, byte[] data) { File appPrivateFile = new File(context.getExternalFilesDir(null), filename); writeBytesToFile(data, appPrivateFile); }