155
Net… work! Yonatan Levin 04/7/2016 Wifi: GoogleGuestPSK pass: pUp3EkaP 4

Android Performance #4: Network

Embed Size (px)

Citation preview

Page 1: Android Performance #4: Network

Net… work!

Yonatan Levin04/7/2016

Wifi: GoogleGuestPSKpass: pUp3EkaP

4

Page 2: Android Performance #4: Network

First,

Page 3: Android Performance #4: Network

Yonatan LevinGoogle Developer Expert

parahall

levin.yonatan

Page 4: Android Performance #4: Network

> 1200 members Largest Android Active Community

Page 5: Android Performance #4: Network

Yonatan Levin

Google Developer Expert & Android @ Gett

Idan Felix

Senior Android & Redhead Varonis

Jonathan Yarkoni

Android Developer & Advocate

Ironsource

Android Academy Staff

Britt Barak

Android LeadStealth Startup

Muiriel Felix

Android Design

Page 6: Android Performance #4: Network

52 Cities > 20M usersRuby, Go, Python, Microservices

Page 7: Android Performance #4: Network

Logistics

Page 8: Android Performance #4: Network

https://www.facebook.com/groups/android.academy.ils/

Page 9: Android Performance #4: Network

What’s next?

10/8 - Felix- Battery & CPU

14/9 - Britt- Threading

Page 10: Android Performance #4: Network

30 / 10 / 2016New course coming

Page 11: Android Performance #4: Network

Special Guest!

Page 12: Android Performance #4: Network

Program Manager at Google

Page 13: Android Performance #4: Network

What’s in menu?- Network- Offline- Scheduler- Batching- Pre-fetching- Whisky

Page 14: Android Performance #4: Network
Page 15: Android Performance #4: Network
Page 16: Android Performance #4: Network

What was I doing wrong?

Page 17: Android Performance #4: Network

Common errors

- Polling chat/message from server every 5 seconds even when app in the background

- Pulling photos/articles from server every time user opens the Gallery even when nothing is changed

- Retrying failing networking requests till them will succeed.- Service that never stops...- A lot of bugs :)

Page 18: Android Performance #4: Network
Page 19: Android Performance #4: Network

What actually happen

Page 20: Android Performance #4: Network

Example

Page 21: Android Performance #4: Network

Example

Page 22: Android Performance #4: Network

Two scenarios

Page 23: Android Performance #4: Network

I want it now!

Page 24: Android Performance #4: Network
Page 25: Android Performance #4: Network

Does it really works for most of the time?

Page 26: Android Performance #4: Network

What we want really to give the user?

Page 27: Android Performance #4: Network
Page 28: Android Performance #4: Network

Ideal world?

Page 29: Android Performance #4: Network
Page 30: Android Performance #4: Network

Let’s start with basics

Page 31: Android Performance #4: Network

1It’s also called HTTP

Net… work

Page 32: Android Performance #4: Network

● Hypertext Transfer Protocol.● This makes HTTP a stateless protocol. The communication

usually takes place over TCP/IP, but any reliable transport can be used. The default port for TCP/IP is 80, but other ports can also be used.

HTTP

Page 33: Android Performance #4: Network

URL

The protocol is typically http, but it can also be https for secure communications.

Page 34: Android Performance #4: Network

HTTP Verb

Specifying the action we want to perform on host

● GET: fetch an existing resource. The URL contains all the necessary information the server needs to locate and return the resource.

● POST: create a new resource. POST requests usually carry a payload that specifies the data for the new resource.

● PUT: update an existing resource. The payload may contain the updated data for the resource.

● DELETE: delete an existing resource.

Page 35: Android Performance #4: Network

Status Code

In return, the server responds with status codes and message payloads

1xx: Informational Messages - Expect: 100-continue

2xx: Successful - 200 OK, 204 No Content

3xx: Redirection - This requires the client to take additional action. The most common use-case is to jump to a different URL in order to fetch the resource.

4xx: Client Error - 404 Not Found, 400 Bad Request,401 Unauthorized,

5xx: Server Error - 503 Service Unavailable

Page 36: Android Performance #4: Network

Request and Response Message Formats

Page 37: Android Performance #4: Network

Request and Response Message Formats

Page 38: Android Performance #4: Network

Request or response message

Page 39: Android Performance #4: Network

Request GET

GET /articles/http-basics HTTP/1.1

Host: www.articles.com

Connection: keep-alive

Cache-Control: no-cache

Pragma: no-cache

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,

*/*;q=0.8

Page 40: Android Performance #4: Network

Response Format

HTTP-Version SP Status-Code SP Reason-Phrase CRLF

HTTP/1.1 200 OK

Page 41: Android Performance #4: Network

HTTP & HTTPS

A TCP stream is broken into IP packets, and it ensures that those packets always arrive in the correct order without fail. HTTP is an application layer protocol over TCP, which is over IP.

Page 42: Android Performance #4: Network

The total overlook

Page 43: Android Performance #4: Network

Should I connect every time?!

Page 44: Android Performance #4: Network

Persistent connection

Page 45: Android Performance #4: Network

Parallel connections

If there are six assets that the client needs to download from a website, the client makes six parallel connections to download those assets, resulting in a faster turnaround.

Page 46: Android Performance #4: Network

Pipelining

Page 47: Android Performance #4: Network

Server side

● establishing a socket to start listening on port 80 (or some other port)

● receiving the request and parsing the message

● processing the response

● setting response headers

● sending the response to the client

● close the connection if a Connection: close request header was found

Page 48: Android Performance #4: Network

2Because really there is only one

HTTP Client

Page 49: Android Performance #4: Network

URL url = new URL(myurl);

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

conn.setReadTimeout(10000 /* milliseconds */);

conn.setConnectTimeout(15000 /* milliseconds */);

conn.setRequestMethod("GET");

conn.setDoInput(true);

// Starts the query

conn.connect();

int response = conn.getResponseCode();

is = conn.getInputStream();

// Convert the InputStream into a string

String contentAsString = readIt(is, len);

return contentAsString;

HttpURLConnection

Page 50: Android Performance #4: Network

Wait! I forgot something!

Page 51: Android Performance #4: Network

NetworkOnMainThreadException

Page 52: Android Performance #4: Network

Brave one that know how to implement readIt(InputStream is)?

Page 53: Android Performance #4: Network

ReadIt()public String readIt(InputStream stream) throws IOException,

UnsupportedEncodingException {

Reader reader = null;

reader = new InputStreamReader(stream, "UTF-8");

char[] buffer = new char[1024];

reader.read(buffer);

return new String(buffer);

}

Page 54: Android Performance #4: Network

What if it’s image?

Page 55: Android Performance #4: Network

Luckily, we have

Page 56: Android Performance #4: Network
Page 57: Android Performance #4: Network

Retrofit 2

A type-safe HTTP client for Android and Java

Page 58: Android Performance #4: Network

build.gradle

dependencies { ... compile 'com.squareup.retrofit2:retrofit:2.1.0' ...}

Page 59: Android Performance #4: Network

public interface UserService {

@POST("me")

Call<User>me();

}

Retrofit retrofit = Retrofit.Builder()

.baseUrl("https://your.api.url/v2/");

.build();

UserService service = retrofit.create(UserService.class);

// the request url for service.me() is:

// https://your.api.url/v2/me

Page 60: Android Performance #4: Network

OkHttp Integrated

Retrofit 2 relies on OkHttp as the HTTP client and has its own dependency to the

library as well

compile 'com.squareup.okhttp3:okhttp:3.3.1'

OkHttpClient client = httpClient.build();

Retrofit retrofit = Retrofit.Builder()

.baseUrl("https://your.api.url/v2/");

.client(client)

.build();

Page 61: Android Performance #4: Network

Why OkHttp called “Ok”?

Page 62: Android Performance #4: Network

InterceptorsOkHttpClient.Builder clientBuilder = new OkHttpClient.

Builder();

clientBuilder.connectTimeout(CONNECTION_TIMEOUT * 1000,

TimeUnit.MILLISECONDS);

clientBuilder.addInterceptor(mGTHeadersInterceptor);

Retrofit gtServiceRetrofit = new Retrofit.Builder()

.baseUrl(mGTBaseUrl)

.client(clientBuilder.build())

.addConverterFactory(GTResponseConverterFactory.create(mGson))

.build();

mGTServiceApi = gtTServiceRetrofit.create(GTServiceApi.class);

Page 63: Android Performance #4: Network

Interceptorspublic class GTHeadersInterceptor implements Interceptor {

public Response intercept(Chain chain) throws IOException {

Request original = chain.request();

// Customize the request

Request request = original.newBuilder()

.header("Accept", "application/json")

.header("Authorization", "auth-token")

.method(original.method(), original.body())

.build();

Response response = chain.proceed(request);

// Customize or return the response

return response;

}

}

Page 64: Android Performance #4: Network

Sync Request

public interface UserService {

@POST("/login")

Call<User> login();

}

// synchronous

Call<User> call = userService.login();

User user = call.execute().body();

Page 65: Android Performance #4: Network

ASycn Request

Call<User> call = userService.login();

call.enqueue(new Callback<User>() {

@Override

public void onResponse(Call<User> call, Response<User> response) {

// response.isSuccessful() is true if the response code is 2xx

}

@Override

public void onFailure(Call<User> call, Throwable t) {

// handle execution failures like no internet connectivity

}

}

Page 66: Android Performance #4: Network

Cancel request

Call<User> call = userService.login();

User user = call.execute().body();

// changed your mind, cancel the request

call.cancel();

Page 67: Android Performance #4: Network

Convertor

Available Converters

● Gson: com.squareup.retrofit2:converter-gson:2.1.0

● Moshi: com.squareup.retrofit2:converter-moshi:2.1.0

● Jackson: com.squareup.retrofit2:converter-jackson:2.1.0

● SimpleXML: com.squareup.retrofit2:converter-simplexml:2.1.0

● ProtoBuf: com.squareup.retrofit2:converter-protobuf:2.1.0

● Wire: com.squareup.retrofit2:converter-wire:2.1.0

Page 68: Android Performance #4: Network

Add convertor

Retrofit retrofit = Retrofit.Builder()

.baseUrl("https://your.api.url/v2/");

.addConverterFactory(ProtoConverterFactory.create())

.addConverterFactory(GsonConverterFactory.create())

.build();

Page 69: Android Performance #4: Network

Multiple Convertors

First come - first server

First fail, pass to next ne

One that succeed - consume the response.

Add the esoteric first and more general like GSON last.

Page 70: Android Performance #4: Network

:הבנת הנקראI want to add query parameter to every

request. What should i do?

Page 71: Android Performance #4: Network

URL

The protocol is typically http, but it can also be https for secure communications.

Page 72: Android Performance #4: Network

Back to requests

@GET("api/dbx/drivers/self/history/{page}/{items_per_page}")

Call<JobsHistoryResponse> getDriverJobsHistory(

@Path("page") int page,

@Path("items_per_page") int itemsPerPage,

@Query("date_from") String dateFrom,

@Query("date_to") String dateTo);

api/dbx/drivers/self/history/1/30?date_from=”01012016”&date_to=”30012016”

Page 73: Android Performance #4: Network

Form

@FormUrlEncoded

@POST("api/dbx/orders/{order_id}/arrival_eta")

Call<VoidResponse> postDriverExternalEtaBeforeArrival(

@Header("Driver-Id") int mDriverId,

@Path("order_id") int orderId,

@Field("directions_eta") long directionsETA);

api/dbx/orders/1235675/arrival_eta

Body: { directions_eta=1235723847328 }

Page 74: Android Performance #4: Network

More read

https://futurestud.io/blog/retrofit-getting-started-and-android-client

Page 75: Android Performance #4: Network

Shot of whisky?

Page 76: Android Performance #4: Network

What if i need different BASE_URL for couple requests?

Page 77: Android Performance #4: Network

Download Image from S3

public interface UserService {

@GET

public Call<ResponseBody> profilePicture(@Url String url);

}

Retrofit retrofit = Retrofit.Builder()

.baseUrl("https://your.api.url/");

.build();

UserService service = retrofit.create(UserService.class);

service.profilePicture("https://s3.amazon.com/profile-picture/path");

Page 79: Android Performance #4: Network

2Execute at right time

Schedulers

Page 80: Android Performance #4: Network

SyncAdapter

Page 81: Android Performance #4: Network

What is it and how i eat that

Android Framework

API >= 7 (Android 2.1)

Synchronizing data between an Android device and web servers

You specify what you should sync , how often - and it will do the rest

Page 82: Android Performance #4: Network

Benefits?

Plug-in architecture

Automated execution

Automated network checking

Improved battery performance

Account management and authentication

Page 83: Android Performance #4: Network

Let’s compareCustom Sync Sync Adapter

Network Availability - manually Network Availability - Automatically

Pending Queue - manually Pending Queue - Automatically

Refresh on Network - manually Refresh on Network - Automatically

Periodic Update - manually Periodic Update - Automatically

Sync Setting - manually Sync Setting - Automatically

Network Bandwidth - manually Network Bandwidth - Automatically

Battery Efficient - ?? Depend on you Battery Efficient - Yes

Survive on Reboot - Depends on you Survive on Reboot - Yes

Page 84: Android Performance #4: Network
Page 85: Android Performance #4: Network

How to?

Sqlite Database: I guess you all are master of Sqlite database, SyncAdapter will store data in

Sqlite using Content Provider. You may choose other options as well.

Content Provider: Act as bridge between your database and SyncAdapter. To expose your

data in Rest like URL pattern.

AbstractAccountAuthenticator: We need to extend this class and override methods, It is

primarily used to manage authentication and account management. To use SyncAdapter you

must have custom account. This class is responsible to create account, maintain auth token.

Page 86: Android Performance #4: Network

How to?

Authenticator Service: This is normal Service, which we are using daily. The only difference

is that this service create object of AbstractAccountAuthenticator class and bind.

AbstractThreadedSyncAdapter: As developer we need to extend this class and override

methods. This is the main piece of SyncAdapter puzzle. It has method onPerformSync, in

which we need to write our code.

Sync Service: This is normal Service. It use to create object of

AbstractThreadedSyncAdapter class and bind.

Page 87: Android Performance #4: Network

How to?Authenticator.xml: You need to create this file under res/xml/ folder. This file is required to bind your

authenticator component into the sync adapter and account frameworks, you need to provide these framework

with metadata that describes the component. You can choose your own file name.

SyncAdapter.xml: You need to create this file under res/xml/ folder. The metadata specifies the account type

you've created for your sync adapter, declares a content provider authority associated with your app.

AndroidManifest.xml: You must register Sync Service, Authenticator service and few other things in

AndroidManifast file in order to work SyncAdapter, This is the final piece of puzzle.

Page 88: Android Performance #4: Network
Page 89: Android Performance #4: Network

JobScheduler/GCMNetworkManager

Page 90: Android Performance #4: Network

What?

Schedule the task to execute it when certain conditions met.

(charging, idle, connected to a network or connected to an unmetered network)

Page 91: Android Performance #4: Network

Why two?

JobScheduler was introduced in API >= 21 (Lollipop).

GCMNetworkManager - is part of GCM package. When using on devices >= 21, use JobScheduler underneath.

Page 92: Android Performance #4: Network

Deep Dive

Page 93: Android Performance #4: Network

build.gradle

dependencies {

...

compile 'com.google.android.gms:play-services-gcm:9.0.2'

...

}

Page 94: Android Performance #4: Network

AndroidManifest.xml

<service

android:name="com.google.codelab.networkmanager.BestTimeService" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"android:exported="true">

<intent-filter>

<action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>

</intent-filter>

</service>

Page 95: Android Performance #4: Network

BestTimeService.java

/**

* Task run by GcmNetworkManager when all the requirements of the scheduled

* task are met.

*/

public class BestTimeService extends GcmTaskService {

...

}

Page 96: Android Performance #4: Network

BestTimeService.java@Override

public int onRunTask(TaskParams taskParams) {

Log.i(TAG, "onRunTask");

switch (taskParams.getTag()) {

case TAG_TASK_ONEOFF_LOG:

Log.i(TAG, TAG_TASK_ONEOFF_LOG);

// This is where useful work would go

return GcmNetworkManager.RESULT_SUCCESS;

case TAG_TASK_PERIODIC_LOG:

Log.i(TAG, TAG_TASK_PERIODIC_LOG);

// This is where useful work would go

return GcmNetworkManager.RESULT_SUCCESS;

default:

return GcmNetworkManager.RESULT_FAILURE;

}

}

Page 97: Android Performance #4: Network

Activity

private GcmNetworkManager mGcmNetworkManager;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

...

mGcmNetworkManager = GcmNetworkManager.getInstance(this);

}

Page 98: Android Performance #4: Network

Scheduling a task

Task task = new OneoffTask.Builder()

.setService(BestTimeService.class)

.setExecutionWindow(0, 30)

.setTag(BestTimeService.TAG_TASK_ONEOFF_LOG)

.setUpdateCurrent(false)

.setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)

.setRequiresCharging(false)

.build();

mGcmNetworkManager.schedule(task);

Page 99: Android Performance #4: Network

What’s in it?

● Service: The specific GcmTaskService that will control the task. This will allow us to cancel it later.

● Execution window: The time period in which the task will execute. First param is the lower bound and the second is the upper bound (both are in seconds). This one is mandatory.

● Tag: We’ll use the tag to identify in the onRunTask method which task is currently being run. Each tag should be unique, and the max length is 100.

Page 100: Android Performance #4: Network

What’s in it?

● Update Current: This determines whether this task should override any pre-existing tasks with the same tag. By default, this is false, so new tasks don’t override existing ones.

● Required Network: Sets a specific network state to run on. If that network state is unavailable, then the task won’t be executed until it becomes available.

● Requires Charging: Whether the task requires the device to be connected to power in order to execute.

Page 101: Android Performance #4: Network

Scheduling a periodic task

Task task = new PeriodicTask.Builder()

.setService(BestTimeService.class)

.setPeriod(30)

.setFlex(10)

.setTag(BestTimeService.TAG_TASK_PERIODIC_LOG)

.setPersisted(true)

.build();

mGcmNetworkManager.schedule(task);

Page 102: Android Performance #4: Network

What’s in it?

● Period: Specifies that the task should recur once every interval at most, where the interval is the input param in seconds. By default, you have no control over where in that period the task will execute. This setter is mandatory.

● Flex: Specifies how close to the end of the period (set above) the task may execute. With a period of 30 seconds and a flex of 10, the scheduler will execute the task between the 20-30 second range.

Page 103: Android Performance #4: Network

What’s in it?

● Persisted: Determines whether the task should be persisted across reboots. Defaults to true for periodic tasks, and is not supported for one-off tasks. Requires “Receive Boot Completed” permission, or the setter will be ignored.

Page 104: Android Performance #4: Network

Cancel Task

mGcmNetworkManager.cancelAllTasks(BestTimeService.class);

mGcmNetworkManager.cancelTask(

BestTimeService.TAG_TASK_PERIODIC_LOG,

BestTimeService.class

);

Page 105: Android Performance #4: Network

There is a problem hiding here

Page 106: Android Performance #4: Network
Page 107: Android Performance #4: Network

Not all devices shipped with Play Services

int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

if (resultCode == ConnectionResult.SUCCESS) {

mGcmNetworkManager.schedule(task);

} else {

// Deal with this networking task some other way

}

Page 108: Android Performance #4: Network

When Google Play updated it removes all scheduled periodic tasks

public class BestTimeService extends GcmTaskService {

@Override

public void onInitializeTasks() {

super.onInitializeTasks();

// Reschedule removed tasks here

}

}

Page 109: Android Performance #4: Network

4Predict what your user will need

Prefetch data

Page 110: Android Performance #4: Network

Prefetch strategy

The goal is simple:

Reduce the number of radio activations required to download the data.

Page 111: Android Performance #4: Network

Result

● Improve the latency,

● Lower the required bandwidth

● Reduce download times.

Page 112: Android Performance #4: Network

User Experience!!!!!

Page 113: Android Performance #4: Network

Strategy

Download the data that has of 50% chance to be used by user in his session

Or

Prefetched data should be enough for 2-5 minutes of use

Page 114: Android Performance #4: Network

Let’s practice!

Page 115: Android Performance #4: Network

Example

Page 116: Android Performance #4: Network

4Minimizing the Effect of Regular Updates

With GCM/FCM

Triggered update

Page 117: Android Performance #4: Network

Polling

ServerOur App

Felix is dancing salsa?

No

Felix is dancing salsa?

No

Felix is dancing salsa?

No

Felix is dancing salsa?

Yes!!!

Page 119: Android Performance #4: Network

What if there is 50M clients?

Page 120: Android Performance #4: Network

GCM and FCM

Page 121: Android Performance #4: Network

GCM and FCM

Page 122: Android Performance #4: Network

How to

dependencies {

compile 'com.google.firebase:firebase-messaging:9.2.0'

}

Page 123: Android Performance #4: Network

<service

android:name=".MyFirebaseMessagingService">

<intent-filter>

<action android:name="com.google.firebase.MESSAGING_EVENT"/>

</intent-filter>

</service>

<service

android:name=".MyFirebaseInstanceIDService">

<intent-filter>

<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>

</intent-filter>

</service>

Page 124: Android Performance #4: Network

public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {

@Override

public void onTokenRefresh() {

// Get updated InstanceID token.

String refreshedToken = FirebaseInstanceId.getInstance().getToken();

sendRegistrationToServer(refreshedToken);

}

}

Page 125: Android Performance #4: Network

https://fcm.googleapis.com/fcm/send

Content-Type:application/json

Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{

"to" : "APA91bHun4MxP5egoKMwt2KZFBaFUH-1RYqx...",

"notification" : {

"body" : "great match!",

"title" : "Portugal vs. Denmark",

"icon" : "myicon"

},

"data" : {

"Nick" : "Mario",

"Room" : "PortugalVSDenmark"

}

}

Page 126: Android Performance #4: Network

Message strategy

● Notifications delivered when your app is in the background. In this case, the

notification is delivered to the device’s system tray. A user tap on a

notification opens the app launcher by default.

● Messages with both notification and data payload. In this case, the notification

is delivered to the device’s system tray, and the data payload is delivered in

the extras of the intent of your launcher Activity.

Page 127: Android Performance #4: Network

public class MyFirebaseMessagingService extends FirebaseMessagingService {

@Override

public void onMessageReceived(RemoteMessage remoteMessage) {

Log.d(TAG, "From: " + remoteMessage.getFrom());

sendNotification(remoteMessage.getNotification().getBody());

}

}

MyFirebaseMessagingService

Page 128: Android Performance #4: Network

4

Don’t download that you already have

Redundant Download

Page 129: Android Performance #4: Network

Don’t download what you already have

Page 130: Android Performance #4: Network

Cache = Last

long currentTime = System.currentTimeMillis();

HttpURLConnection conn = (HttpURLConnection) url.openConnection();

long expires = conn.getHeaderFieldDate("Expires", currentTime);

long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime);

setDataExpirationDate(expires);

if (lastModified < lastUpdateTime) {

// Skip update

} else {

// Parse update

}

Page 131: Android Performance #4: Network

How to do that in Retrofit?

Page 132: Android Performance #4: Network

4

The shy guy that no shy anymore

Doze Mode

Page 133: Android Performance #4: Network

Doze, the bro :)

No network access

No jobs

No syncs

No wakelocks

No alarms

GPS

Page 134: Android Performance #4: Network
Page 135: Android Performance #4: Network

Doze Mode on Marshmallow

Page 136: Android Performance #4: Network

Not shy anymore

Page 137: Android Performance #4: Network

Doze Mode on Nougat

Page 138: Android Performance #4: Network

Doze Mode on Nougat

Page 139: Android Performance #4: Network

Doze, bye

- User pickup the phone- User plug the phone to the charger- Real alarm (clock) is going to kick on

Page 140: Android Performance #4: Network

So how i survive my background service to track Felix?

Page 141: Android Performance #4: Network

Will doze mode affect my app?

Page 142: Android Performance #4: Network

GCM

Use GCM with High priority - but treat it with special care

{

"to" : "...",

"priority" : "high",

"notification" : {

...

},

"data" : {

...

}

}

Page 144: Android Performance #4: Network

WhiteList

● An app can fire the ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS intent to take the user directly to the Battery Optimization, where they can add the app.

● An app holding the REQUEST_IGNORE_BATTERY_OPTIMIZATIONS permission can trigger a system dialog to let the user add the app to the whitelist directly, without going to settings. The app fires a ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS Intent to trigger the dialog.

● The user can manually remove apps from the whitelist as needed.

Page 146: Android Performance #4: Network

Note: Google Play policies prohibit apps from requesting direct exemption from Power

Management features in Android 6.0+ (Doze and App Standby) unless the core function of

the app is adversely affected.

Page 147: Android Performance #4: Network

Payload

Because size is matter4

Page 148: Android Performance #4: Network

Serialization

Flatbuffers4

Page 149: Android Performance #4: Network

Serialization/Deserialization

Serialization Deserialization

Page 150: Android Performance #4: Network

JSON Class Representation

{

"starwars": {

"number_of_episodes": 1,

"realDarthVaderName": "Anakin Skywalker",

"nextEpisodeRelease": "01-12-2016 01:00:00+3:00GMT"

}

}

Page 151: Android Performance #4: Network

Serialization/Deserialization

Advantage - It’s human readable. And it’s biggest weak point.

Memory overhead

Page 152: Android Performance #4: Network

- Faster- Lighter

FlatBuffers

Page 153: Android Performance #4: Network

How it works?

Page 154: Android Performance #4: Network

Process

1. Create schema2. Compile schema with flatc compiler3. Import generated files into your project4. Read from byte[]:

java.nio.ByteBuffer buf = builder.dataBuffer();

// Deserialize the data from the buffer.

StarWars starWars = StarWars.getRootAsStarWars(buf);

Page 155: Android Performance #4: Network