Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Programming: Better and Smarter Networking

Android Programming: Better and Smarter Networking

Presentation done at Istanbul Tech Talks 2014 about improving networking in your mobile apps with focus on Android.

Erik Hellman

May 12, 2014
Tweet

More Decks by Erik Hellman

Other Decks in Programming

Transcript

  1. Erik Hellman • Engineer @ Ericsson • Lead Architect @

    Sony Mobile • Research Engineer @ Sony • Android Developer @ Spotify • Speaking at dev conferences • Wrote a book on Android
  2. • Reduce battery consumption! • Reduce data traffic! • Improve

    UI performance! • Reduce cost of backend services
  3. Network and Battery • Mobile data uses more battery than

    WiFi • Connections (sockets) linger longer on a mobile network • Battery drains faster if network activity changes frequently
  4. Network and Battery • Stay more passive when on mobile

    network • Always make sure you properly close all your connections! • Try to perform all network operations in a tight sequence and together with other apps (see AlarmManager)
  5. Networking Optimisations • Reduce payload size • Better protocol stack

    • Better networking strategy • Better app design
  6. Reduce payload size • JSON • {“name”:"Erik  Hellman","age":37} - 32

    bytes • Google Protobuf (hexadecimal) • 0a  0c  45  72  69  6b  20  48  65  6c  6c  6d  61   6e  10  25  - 16 bytes
  7. Protobuf in Android dependencies  {          compile

     fileTree(dir:  'libs',  include:  ['*.jar'])          compile  'com.android.support:appcompat-­‐v7:19.+'          compile  'com.squareup.wire:wire-­‐runtime:1.4.0'   } build.gradle:
  8. Protobuf in Android: Schema package  se.hellsoft.bettersmarternetworking;   ! option  java_package

     =  "se.hellsoft.bettersmarternetworking";   ! message  SimpleMessage  {          enum  State  {                    STOPPED  =  1;                  PREPARED  =  2;                  RUNNING  =  3;                  PAUSED  =  4;                  ERROR  =  5;          }   !        required  int32  message_id  =  1;  //  Unique  id  for  each  element          optional  int64  timestamp  =  2;            required  State  server_state  =  3;          optional  string  title  =  4;          required  bytes  content  =  5;  //  A  byte  array   } messages.proto:
  9. Protobuf in Android: Generate Java code $ java -jar ../wire-compiler-1.4.0-jar-with-dependencies.jar

    \
 --java_out=app/src/main/java/ messages.proto Run in console:
  10. Protobuf in Android: Java usage public  SimpleMessage  deserializeMessage(byte[]  data)  throws

     IOException  {     Wire  wire  =  new  Wire();     return  wire.parseFrom(data,  SimpleMessage.class);   }       public  byte[]  buildAndSerialize(int  msgId,  long  timestamp,                                                                    SimpleMessage.State  state,                                                                    String  title,  byte[]  content)  {     SimpleMessage.Builder  builder  =  new  SimpleMessage.Builder();     SimpleMessage  simpleMessage  =  builder.message_id(msgId)         .timestamp(timestamp).server_state(state)         .title(title).content(ByteString.of(content)).build();     return  simpleMessage.toByteArray();   } Java code using Protobuf:
  11. Better protocol stack • Apache HttpClient (AndroidHttpClient) - Avoid! •

    HttpURLConnection (Default on Android) - Ok… • OkHttp (Third-party. Support SPDY) - Better :)
  12. HTTP/1.1 • Old (1999) • Insecure (No default encryption) •

    Bloated (Only content can be compressed) • Blocking (Only one request at a time per socket)
  13. SPDY (and HTTP/2) • Always encrypted • Header compression •

    Multiplexing requests and responses • Server-side push
  14. OkHttp in Android public  void  doOkHttpDemo(URL  url)  throws  IOException  {

        OkHttpClient  okHttpClient  =  new  OkHttpClient();     HttpURLConnection  httpURLConnection  =  okHttpClient.open(url);     if(httpURLConnection.getResponseCode()  ==  HttpURLConnection.HTTP_OK)  {       //  TODO  Read  response...     }     httpURLConnection.disconnect();   }   dependencies  {          compile  fileTree(dir:  'libs',  include:  ['*.jar'])          compile  'com.android.support:appcompat-­‐v7:19.+'          compile  'com.squareup.okhttp:okhttp:1.5.4'   }
  15. Networking strategy • Server-Side Push (Google Cloud Messaging etc.) •

    Polling at recurring intervals • Triggered by system event • On-demand
  16. Google Cloud Messaging • Eliminates all redundant network calls •

    Always up to date • Requires Google Play, a Google account and dependencies towards Google Cloud.
  17. Polling with AlarmManager • Polling of data at regular intervals

    • Will generate redundant network calls • No dependency on Google services or accounts
  18. Using AlarmManager public  void  doAlarmManagerPolling(Context  context)  {     AlarmManager

     alarmManager  =  (AlarmManager)  context         .getSystemService(Context.ALARM_SERVICE);         Intent  syncNetwork  =  new  Intent(NetworkSync.ACTION_SYNC_NETWORK);     syncNetwork.setComponent(new  ComponentName(context,  NetworkSync.class));         PendingIntent  pendingIntent  =  PendingIntent.getService(context,  0,                                    syncNetwork,  0);         alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME,  0,           AlarmManager.INTERVAL_HALF_HOUR,  pendingIntent);   }  
  19. Triggered by events • Activity.onResume() - User started your app

    • Intent.ACTION_USER_PRESENT - User unlocked device • AlarmManager.setExact() - Trigger at exact time • WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION - Connected to a WiFi (with specifics about SSID)
  20. Improving app design • Use the Android components correctly! •

    Don’t reinvent the wheel! • Design for vanilla Android!
  21. Android Components Service Activity BroadcastReceiver ContentProvider Should only be used

    for UI! Anything long running not related to UI Persisting data Receiving (system) events
  22. Very Common App Design public  void  doRefreshNetwork(View  view)  {  

      new  AsyncTask<URL,  Void,  JSONArray>()  {   !     @Override       protected  JSONArray  doInBackground(URL...  params)  {         try  {           HttpURLConnection  connection  =                 (HttpURLConnection)  params[0].openConnection();           if(connection.getResponseCode()  ==  HttpURLConnection.HTTP_OK)  {             JSONArray  result  =  null;             //  Parse  JSON  response..             return  result;           }         }  catch  (IOException  e)  {           //  TODO  error  handling         }         return  null;       }   !     @Override       protected  void  onPostExecute(JSONArray  jsonArray)  {         super.onPostExecute(jsonArray);         mJsonArrayAdapter.setJSONArray(jsonArray);         mJsonArrayAdapter.notifyDataSetChanged();       }     }.execute(REST_API_URL);   }
  23. Better App Design Activity + ListView + Loader Service ContentProvider

    startService() getContentResolver().insert() HttpUrlConnection getContentResolver().notifyChange(); BroadcastReceiver Network changed!
  24. Additional tips • Use latest tools (Android Studio, Gradle etc.)!

    • Loading images is tricky - use a library! • Picasso - http://square.github.io/picasso/ • Cancel requests properly (ListView etc.) • Close sockets and connection properly! • Batch network data if possible! • Using paging and caching when possible! • Listen for network and configuration changes!
  25. Sum it up… • 3G acts differently than WiFi! •

    Consider a different data format! • Pick a better protocol stack! • Server push, polling at interval or system event? • Design your app correctly - don’t re-invent the wheel!
  26. Useful links ! • https://github.com/square/wire - Protobuf library • http://blog.chromium.org/2013/11/making-web-faster-with-spdy-

    and-http2.html - Great article about SPDY and HTTP/2 • http://square.github.io/okhttp/ - HTTP client supporting SPDY • http://square.github.io/picasso/ - Powerful image loading library • http://developer.android.com/training/building-connectivity.html - Android documentation on networking • www.wiley.com/go/ptl/androidprogramming - My book :)