Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

No internet? No Problem! Slide 1 No internet? No Problem! Slide 2 No internet? No Problem! Slide 3 No internet? No Problem! Slide 4 No internet? No Problem! Slide 5 No internet? No Problem! Slide 6 No internet? No Problem! Slide 7 No internet? No Problem! Slide 8 No internet? No Problem! Slide 9 No internet? No Problem! Slide 10 No internet? No Problem! Slide 11 No internet? No Problem! Slide 12 No internet? No Problem! Slide 13 No internet? No Problem! Slide 14 No internet? No Problem! Slide 15 No internet? No Problem! Slide 16 No internet? No Problem! Slide 17 No internet? No Problem! Slide 18 No internet? No Problem! Slide 19 No internet? No Problem! Slide 20 No internet? No Problem! Slide 21 No internet? No Problem! Slide 22 No internet? No Problem! Slide 23 No internet? No Problem! Slide 24 No internet? No Problem! Slide 25 No internet? No Problem! Slide 26 No internet? No Problem! Slide 27 No internet? No Problem! Slide 28 No internet? No Problem! Slide 29 No internet? No Problem! Slide 30 No internet? No Problem! Slide 31 No internet? No Problem! Slide 32 No internet? No Problem! Slide 33 No internet? No Problem! Slide 34 No internet? No Problem! Slide 35 No internet? No Problem! Slide 36 No internet? No Problem! Slide 37 No internet? No Problem! Slide 38 No internet? No Problem! Slide 39 No internet? No Problem! Slide 40 No internet? No Problem! Slide 41 No internet? No Problem! Slide 42 No internet? No Problem! Slide 43 No internet? No Problem! Slide 44 No internet? No Problem! Slide 45 No internet? No Problem! Slide 46 No internet? No Problem! Slide 47 No internet? No Problem! Slide 48 No internet? No Problem! Slide 49 No internet? No Problem! Slide 50 No internet? No Problem! Slide 51 No internet? No Problem! Slide 52 No internet? No Problem! Slide 53 No internet? No Problem! Slide 54 No internet? No Problem! Slide 55 No internet? No Problem! Slide 56 No internet? No Problem! Slide 57 No internet? No Problem! Slide 58 No internet? No Problem! Slide 59 No internet? No Problem! Slide 60 No internet? No Problem! Slide 61 No internet? No Problem! Slide 62 No internet? No Problem! Slide 63 No internet? No Problem! Slide 64 No internet? No Problem! Slide 65 No internet? No Problem! Slide 66 No internet? No Problem! Slide 67 No internet? No Problem! Slide 68 No internet? No Problem! Slide 69 No internet? No Problem! Slide 70 No internet? No Problem! Slide 71 No internet? No Problem! Slide 72 No internet? No Problem! Slide 73 No internet? No Problem! Slide 74 No internet? No Problem! Slide 75 No internet? No Problem! Slide 76 No internet? No Problem! Slide 77 No internet? No Problem! Slide 78 No internet? No Problem! Slide 79 No internet? No Problem! Slide 80 No internet? No Problem! Slide 81 No internet? No Problem! Slide 82 No internet? No Problem! Slide 83
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

2 Likes

Share

Download to read offline

No internet? No Problem!

Download to read offline

At Off Grid Electric our mission is to power homes across rural Africa with affordable, solar energy. In order to do that we need to provide our employees with tools that work both on and offline. So how did we do it? In this talk, learn about the techniques we employed to provide a unique online-offline experience in our Android applications. We’ll discuss the overall architecture, third party libraries used, and some of the challenges that we faced. As more and more users come online in various parts of the world it makes sense for companies to begin exploring how they can modify their applications to be more network-friendly. This talk will get you headed in the right direction!

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

No internet? No Problem!

  1. 1. NO INTERNET? NO PROBLEM!
  2. 2. OFF GRID ELECTRIC From: https://medium.com/@Offgrid
  3. 3. OFF GRID ELECTRIC
  4. 4. AGENDA ARCHITECTURE LIBRARIES CHALLENGES
  5. 5. CHALLENGES
  6. 6. 3G COVERAGE IN ARUSHA, TZ
  7. 7. 4G LTE COVERAGE IN WASHINGTON, DC
  8. 8. DON’T ASSUME BE RESILIENT
  9. 9. ARCHITECTURE
  10. 10. BE USEFUL Our App ‣Store data locally ‣Separate UI and network ‣Queue requests
  11. 11. MVP(Model View Presenter)
  12. 12. EVENT BUS/RXJAVA DATABASE REPOSITORY REPOSITORY ACTIVITY FRAGMENT JOBS PRESENTER PRESENTER SERVICE
  13. 13. DOWNLOAD ALL THE THINGS
  14. 14. DISPLAY A VIEW Is pre-populated data needed?
  15. 15. EVENT BUS/RXJAVA FRAGMENT PRESENTER SERVICE REPOSITORY DATABASE
  16. 16. TAKE AN ACTION Is the Network Available?
  17. 17. EVENT BUS/RXJAVA FRAGMENT PRESENTER SERVICE REPOSITORY DATABASE JOB
  18. 18. APP SERVER
  19. 19. CONFLICT RESOLUTION
  20. 20. REQUEST TIMESTAMPS
  21. 21. STATUS FIELDS ACTION STATE
  22. 22. BUNDLING REQUESTS /users/commissions /users/info /users/roles
  23. 23. BUNDLING REQUESTS /users/commissions /users/info /users/roles /users/me
  24. 24. EVENT BUS/RXJAVA DATABASE REPOSITORY REPOSITORY ACTIVITY FRAGMENT JOBS PRESENTER PRESENTER SERVICE
  25. 25. LIBRARIES
  26. 26. WHAT WE USE ‣Realm ‣EventBus ‣Android Job
  27. 27. STORE DATA LOCALLY
  28. 28. REALM - MODEL CLASS @RealmClass
 public class Place implements RealmModel {
 }
  29. 29. REALM - MODEL CLASS @RealmClass
 public class Place implements RealmModel {
 @PrimaryKey
 private String localId; @Index
 private Long remoteId;
 private Gps location; … }
  30. 30. REALM - MODEL CLASS localId remoteId location 19444498-2a40… 1458260 65031f36-bde9… e85c9757-f546…
  31. 31. REALM - ADDING A RECORD public class PlaceRepository implements Repository<Place> {
 @Override
 public void add (final Place item) {
 
 } …
  32. 32. REALM - ADDING A RECORD public class PlaceRepository implements Repository<Place> {
 @Override
 public void add (final Place item) {
 Realm realm = Realm.getDefaultInstance();
 realm.executeTransaction((realm) -> {
 realm.insertOrUpdate(item);
 });
 realm.close();
 } …
  33. 33. REALM - QUERY RESULT @Override
 public Place toResult (Realm realm) {
 return realm.where(Place.class)
 
 }
  34. 34. REALM - QUERY RESULT @Override
 public Place toResult (Realm realm) {
 return realm.where(Place.class)
 .equalTo(PLACE_ID, placeId)
 .findFirst();
 }
  35. 35. REALM - QUERY RESULT @Override
 public Place toResult (Realm realm) {
 return realm.where(Place.class)
 .equalTo(PLACE_ID, placeId)
 .findFirst();
 }
  36. 36. SEPARATE UI AND NETWORK
  37. 37. EVENTBUS From: http://greenrobot.org/eventbus
  38. 38. EVENTBUS - SETUP @Provides
 @Singleton
 public Bus provideBus () {
 return new Bus(EventBus.builder()
 .logNoSubscriberMessages(BuildConfig.DEBUG)
 .throwSubscriberException(false)
 .build());
 }
  39. 39. EVENTBUS - REGISTER public class LeadsMapPresenter {
 private final Bus bus;
 private LeadsMapView leadsMapView;
 
 @Inject
 LeadsMapPresenter (Bus bus) {
 this.bus = bus;
 }
 
 …
  40. 40. EVENTBUS - REGISTER public class LeadsMapPresenter { 
 public void attachView (LeadsMapView view) {
 this.leadsMapView = view;
 bus.register(this);
 }
  41. 41. EVENTBUS - REGISTER public class LeadsMapPresenter { 
 public void attachView (LeadsMapView view) {
 …
 } public void detachView () {
 this.leadsMapView = null;
 bus.unregister(this);
 }
  42. 42. EVENT BUS/RXJAVA FRAGMENT PRESENTER SERVICE REPOSITORY DATABASE JOB
  43. 43. EVENTBUS - POST EVENT api.submitPlace(place).enqueue(new Callback<Place>() {
 … JOB
  44. 44. EVENTBUS - POST EVENT api.submitPlace(place).enqueue(new Callback<Place>() {
 
 public void onResponse (…, Response<Place> response) {
 if (response.isSuccessful()) {
 
 } … JOB
  45. 45. EVENTBUS - POST EVENT api.submitPlace(place).enqueue(new Callback<Place>() {
 
 public void onResponse (…, Response<Place> response) {
 if (response.isSuccessful()) {
 Place updatedPlace = response.body();
 bus.post(new PlaceSubmissionSuccessEvent(updatedPlace));
 } … JOB
  46. 46. EVENTBUS - RETRIEVE EVENT public class LeadsMapPresenter { 
 @Subscribe
 public void handle (PlaceSubmissionSuccessEvent event) {
 leadsMapView.displaySuccessMessage(); } … PRESENTER
  47. 47. EVENTBUS - SEND STATUS BAR NOTIFICATION SERVICE
  48. 48. EVENTBUS - SEND STATUS BAR NOTIFICATION SERVICE @Subscribe(priority = 1) open fun onEvent(event: PaymentSuccessEvent) { }
  49. 49. EVENTBUS - SEND STATUS BAR NOTIFICATION SERVICE @Subscribe(priority = 1) open fun onEvent(event: PaymentSuccessEvent) { val notif = getString(R.string.payment_submitted_message) createNotification(notif, 1) }
  50. 50. QUEUE REQUESTS
  51. 51. ANDROID JOB
  52. 52. ANDROID JOB ‣Alarm Manager ‣Job Scheduler ‣GCM Network Manager
  53. 53. ANDROID JOB - COMPARISON Library Min API Google Play? JobScheduler 21 No Firebase Job Dispatcher 9 Yes Android Job 14 No
  54. 54. ANDROID JOB JOB MANAGER JOB CREATOR
  55. 55. ANDROID JOB JOB MANAGER PROVIDER JOB JOB CREATOR PROVIDER JOB PROVIDER JOB
  56. 56. ANDROID JOB JOB MANAGER PROVIDER JOB JOB CREATOR PROVIDER JOB PROVIDER JOB JOB REQUEST
  57. 57. ANDROID JOB JOB MANAGER PROVIDER JOB JOB CREATOR PROVIDER JOB PROVIDER JOB JOB REQUEST JOB
  58. 58. ANDROID JOB - CREATOR public class ConfettiJobCreator implements JobCreator {
 
 Map<String, Provider<Job>> jobs;
 
 public Job create (String tag) {
 
 }
 }
  59. 59. ANDROID JOB - CREATOR public Job create (String tag) {
 Provider<Job> jobProvider = jobs.get(tag);
 return jobProvider.get();
 }
  60. 60. ANDROID JOB JOB MANAGER PROVIDER JOB JOB CREATOR JOB REQUEST JOB
  61. 61. ANDROID JOB - JOB EXECUTION protected Result onRunJob (final Params params) {
 
 } JOB
  62. 62. ANDROID JOB - JOB EXECUTION protected Result onRunJob (final Params params) {
 PersistableBundleCompat extras = params.getExtras();
 String placeId = extras.getString(PARAM_PLACE_ID);
 
 
 } JOB
  63. 63. ANDROID JOB - JOB EXECUTION protected Result onRunJob (final Params params) {
 PersistableBundleCompat extras = params.getExtras();
 String placeId = extras.getString(PARAM_PLACE_ID);
 
 return submitRequest(placeId) ? SUCCESS: FAILURE;
 } JOB
  64. 64. ANDROID JOB JOB MANAGER PROVIDER JOB JOB CREATOR JOB REQUEST JOB
  65. 65. ANDROID JOB - SCHEDULING public static JobRequest get (String placeId) {
 PersistableBundleCompat extras = …;
 extras.putString(PARAM_PLACE_ID, placeId);
 
 
 }
  66. 66. ANDROID JOB - SCHEDULING public static JobRequest get (String placeId) {
 PersistableBundleCompat extras = …;
 extras.putString(PARAM_PLACE_ID, placeId);
 
 return new JobRequest.Builder(SendPlaceRequestJob.JOB_TAG)
 
 }
  67. 67. ANDROID JOB - SCHEDULING public static JobRequest get (String placeId) {
 PersistableBundleCompat extras = …;
 extras.putString(PARAM_PLACE_ID, placeId);
 
 return new JobRequest.Builder(SendPlaceRequestJob.JOB_TAG)
 .setExecutionWindow(10_000L, 20_000L)
 .setRequiredNetworkType(NetworkType.CONNECTED)
 
 }
  68. 68. ANDROID JOB - SCHEDULING public static JobRequest get (String placeId) {
 PersistableBundleCompat extras = …;
 extras.putString(PARAM_PLACE_ID, placeId);
 
 return new JobRequest.Builder(SendPlaceRequestJob.JOB_TAG)
 .setExecutionWindow(10_000L, 20_000L)
 .setRequiredNetworkType(NetworkType.CONNECTED)
 .setExtras(extras)
 
 }
  69. 69. ANDROID JOB - SCHEDULING public static JobRequest get (String placeId) {
 PersistableBundleCompat extras = …;
 extras.putString(PARAM_PLACE_ID, placeId);
 
 return new JobRequest.Builder(SendPlaceRequestJob.JOB_TAG)
 .setExecutionWindow(10_000L, 20_000L)
 .setRequiredNetworkType(NetworkType.CONNECTED)
 .setExtras(extras)
 .setRequirementsEnforced(true)
 .build();
 }
  70. 70. if has network connection attempt to submit request
  71. 71. if has network connection attempt to submit request else queue request
  72. 72. ANDROID JOB - SCHEDULING jobManager.schedule( );
  73. 73. ANDROID JOB - SCHEDULING jobManager.schedule(SendPlaceRequestJob.buildJobRequest(id)); JOB REQUEST JOB QUEUE
  74. 74. WHAT WE USE ‣Realm ‣EventBus ‣Android Job
  75. 75. WHAT’S NEXT? ‣SMS Fallback ‣Async Code Paths ‣Push Notifications
  76. 76. THANKS @brwngrldev adavis.info --- @moyheen medium.com/@moyinoluwa
  • samiso

    Oct. 1, 2017
  • IsmailIbrahim51

    Sep. 26, 2017

At Off Grid Electric our mission is to power homes across rural Africa with affordable, solar energy. In order to do that we need to provide our employees with tools that work both on and offline. So how did we do it? In this talk, learn about the techniques we employed to provide a unique online-offline experience in our Android applications. We’ll discuss the overall architecture, third party libraries used, and some of the challenges that we faced. As more and more users come online in various parts of the world it makes sense for companies to begin exploring how they can modify their applications to be more network-friendly. This talk will get you headed in the right direction!

Views

Total views

1,219

On Slideshare

0

From embeds

0

Number of embeds

37

Actions

Downloads

20

Shares

0

Comments

0

Likes

2

×