SlideShare a Scribd company logo
1 of 55
Build a sustainable app with an IPC
mechanism
IPC: AIDL is Sexy, not a
curse
Yonatan Levin
> 10M users
Ruby, Golang,
Python,
Android, iOS
52 cities
> 1000
members
Largest
StudyJam
in the World
Android
Academy
What are we going to do?
Learn how to talk
➔Became best fellows with IPC
➔Best friends with Binder
➔Fall in love with AIDL
Goal:
Make our app run smooth in the background while
performing multiple long tasks (like playing music)
unrelated to the UI
DarthVaderActivity
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.darth_vader_activity);
findViewById(R.id.iv_dva_build_death_star).setOnClickListener(this);
findViewById(R.id.iv_dva_interact_with_luke).setOnClickListener(this);
}
EmpireService
<service
android:name=".EmpireService"
android:enabled="true"
android:process=":remote">
</service>
Why separate process?
● GC not affecting your app
● Crashing not affecting UI
● Less chance to be killed:
○ Process serving others has at least the ranking of those it serve
○ Process with Service > Process with Background activities
● New Heap Space
● Smaller cold start + resource efficiency
● Because we can! :)
Why and when not?
●If you don’t have driver licenses
●Memory leaks
●Two process
●Keep it simple, stupid
https://github.com/parahall/AIDLServiceExample.git
Try this at home
IPC?
Inter-process communication (IPC)
is a framework for the exchange of
signals and data across multiple
processes
Linux legacy
Android
Why Binder?
Performance Security Stability Memory
Benefit for free
●Thread migration
●Identifying senders to receivers
●Unique object-mapping across process
●AIDL!!!!
●Bult-in support for marshalling
●Local execution mode (no IPC) if same process
We are already using binder today
●LifeCycle callbacks (onResume, OnDestroy) invoked by
ActivityManagerService
●Intents
●Content Provider
1
IPC using Intent
git checkout IPCwithIntent
DarthVaderActivity
@Override
public void onClick(View v) {
Intent intent = new Intent(this, EmpireService.class);
switch (v.getId()) {
case R.id.iv_dva_build_death_star:
intent.putExtra(COMMAND_TYPE,
EmpireService.EmpireServiceCommands.BUILD_DEATH_STAR);
break;
case R.id.iv_dva_interact_with_luke:
intent.putExtra(COMMAND_TYPE,
EmpireService.EmpireServiceCommands.FIND_LUKE);
break;
}
mStartedCommandTime = System.currentTimeMillis();
startService(intent);
}
DarthVaderActivity
public class EmpireServiceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"Time took: " +String.valueOf(System.currentTimeMillis()-
mStartedCommandTime));
Toast.makeText(DarthVaderActivity.this, "Death Star deployed and ready for
your command, my lord",
Toast.LENGTH_LONG).show();
}
}
EmpireService
public int onStartCommand(Intent intent, int flags, int startId) {
EmpireServiceCommands command = (EmpireServiceCommands) intent.getExtras()
.get(COMMAND_TYPE);
switch (command) {
case BUILD_DEATH_STAR:
..do some hard work...
Intent jobDoneIntent = new Intent(EMPIRE_SERVICE_ACTION);
jobDoneIntent.putExtra("result",
new DeathStar(270000, 270000, "THIS IS THE BIG GUN"));
sendBroadcast(jobDoneIntent);
break;
case FIND_LUKE:
break;
}
stopSelf();
return START_NOT_STICKY;
}
Pain?
Not really OOP
Async only
Loosely-defined
Not so fast
High Level Abstraction of Binder
2
IPC using Messenger
git checkout IPCwithMessenger
A reference to a Handler that can be sent to a remote process via
an Intent
Messages sent by the remote process via the messenger are
delivered to the local handler
Relatively fast
Overview
DarthVaderActivity
public void onClick(View v) {
Intent intent = new Intent(this, EmpireService.class);
Messenger messenger = new Messenger(new DarthVaderHandler(this));
intent.putExtra("ImperialMessenger", messenger);
switch (v.getId()) {
case R.id.iv_dva_build_death_star:
intent.putExtra("Command type",
EmpireService.EmpireServiceCommands.BUILD_DEATH_STAR);
break;
case R.id.iv_dva_interact_with_luke:
intent.putExtra("Command type",
EmpireService.EmpireServiceCommands.FIND_LUKE);
break;
}
startService(intent);
}
DarthVaderActivity
private static class DarthVaderHandler extends Handler {
private final WeakReference<DarthVaderActivity> clientRef;
public DarthVaderHandler(DarthVaderActivity client) {
this.clientRef = new WeakReference<>(client);
}
...//Handle message
}
DarthVaderActivity
private static class DarthVaderHandler extends Handler {
@Override
public void handleMessage(Message msg) {
Bundle data = msg.getData();
DarthVaderActivity client = clientRef.get();
if (client != null && msg.what == EmpireService.CALLBACK_MSG && data != null) {
Toast.makeText(client, "Death Star deployed and ready for your command, my lord",
Toast.LENGTH_LONG).show();
}
}
}
EmpireService
public int onStartCommand(Intent intent, int flags, int startId) {
Messenger messenger = intent.getParcelableExtra("ImperialMessenger");
EmpireServiceCommands command = (EmpireServiceCommands) intent.getExtras()
.get("Command type");
… more code coming...
EmpireService
switch (command) {
case BUILD_DEATH_STAR:
..do some hard work...
if (messenger != null) {
Message message = Message.obtain();
message.what = CALLBACK_MSG;
Bundle data = new Bundle(1);
data.putParcelable("result",
new DeathStar(270000, 270000, "THIS IS THE BIG GUN"));
message.setData(data);
try {
messenger.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
But what if...
We want sync calls?
Full OOP
Business Transparent
3
IPC using AIDL
git checkout IPCwithAIDL
Android Interface Definition Language (AIDL)
Our business operation on top of Binder object
Java-like interface
Defined in a separate .aidl file
AIDL Generate code of real java interface
.AIDL interface
interface IStarWars {
String buildDeathStar(out DeathStar deathStar);
oneway void findLuke(in IEmpireServiceResponseListener listener);
}
DeathStar.aidl
package com.academy.android.aidlserviceexample;
// Declare DeathStar so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable DeathStar;
IEmpireServiceResponseListener.aidl
interface IEmpireServiceResponseListener {
void onResponse(String response);
}
IStarWars.Stub
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder
implements com.academy.android.aidlserviceexample.IStarWars {
@Override
public java.lang.String buildDeathStar(
com.academy.android.aidlserviceexample.DeathStar deathStar)
throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_buildDeathStar, _data, _reply, 0);
… not really necessary to dig in
Interface directional flag
in means that the object is transferred from client to service and
only used for inputs. If any changes are made to the bar object in
the service then they won’t reflect in the client.
out indicates that the object has no relevant data and will be
populated by the service and returned as a response.
inout means that the data gets copied, i.e., if any changes are
made to bar in the service then that’ll also reflect in the client’s
bar object.
AIDL Data Types
All primitives and arrays of
primitives
FileDescriptor
Serializable/Parcelable****
Map
Bundle
List
SparseArray
Sync Call - Death Star
Let the fun begin!
IStarWarsImplementation
public class IStarWarsImplementation extends IStarWars.Stub {
public String buildDeathStar(DeathStar deathStar) throws RemoteException {
...doing hard work..
deathStar.setBFG("BIG GUN IS VERY VERY");
deathStar.setHeight(270000);
deathStar.setWidth(270000);
return "Death Star deployed and ready for your command, my lord";
}
…
other interface methods
EmpireService
public class EmpireService extends Service {
private IStarWarsImplementation service;
@Override
public void onCreate() {
super.onCreate();
service = new IStarWarsImplementation();
}
EmpireService
@Override
public IBinder onBind(Intent intent) {
return service;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
@Override
public void onDestroy() {
this.service = null;
super.onDestroy();
}
DarthVaderActivity
public class DarthVaderActivity extends Activity implements ServiceConnection {
@Override
protected void onResume() {
super.onResume();
final boolean isServiceBounded = super.bindService(new Intent(this,
EmpireService.class),
this, BIND_AUTO_CREATE);
if (!isServiceBounded) {
Log.w(TAG, "Failed to bind to service");
}
}
… more methods
DarthVaderActivity
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
this.service = IStarWars.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
this.service = null;
}
DarthVaderActivity
@Override
public void onClick(View v) {
try {
switch (v.getId()) {
case R.id.iv_dva_build_death_star:
DeathStar deathStar = new DeathStar();
final String reply = service.buildDeathStar(deathStar);
String buildDeathStar = String
.format("%s and it have %s", reply, deathStar.getBFG());
Toast.makeText(this, buildDeathStar, Toast.LENGTH_LONG).show();
break;
}
} catch (RemoteException e) {
e.printStackTrace();
}
ASync Call - Find a luke
.AIDL interface
interface IStarWars {
String buildDeathStar(out DeathStar deathStar);
oneway void findLuke(in IEmpireServiceResponseListener listener);
}
interface IEmpireServiceResponseListener {
void onResponse(String response);
}
IStarWarsImplementation
...other AIDL interface implementation methods
@Override
public void findLuke(IEmpireServiceResponseListener listener) throws RemoteException
{
..Doing very hard job through couple episodes…
listener.onResponse("I'm your father, Luke!");
}
DarthVaderActivity
IEmpireServiceResponseListener.Stub mListener
= new IEmpireServiceResponseListener.Stub() {
@Override
public void onResponse(final String response) throws RemoteException {
//Other process. We should run on UI Thread in order to interact with UI
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(DarthVaderActivity.this, response,
Toast.LENGTH_LONG)
.show();
}
});
}
};
DarthVaderActivity
@Override
public void onClick(View v) {
try {
switch (v.getId()) {
case R.id.iv_dva_interact_with_luke:
service.findLuke(mListener);
break;
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
Binder Overhead:
0 ms
What did we get?
Services running on separate process
Easy expandable communication
Great performance
Fun :)
levinyon@gmail.com
facebook.com/levin.yonatan

More Related Content

What's hot

Oracle WebLogic Server Basic Concepts
Oracle WebLogic Server Basic ConceptsOracle WebLogic Server Basic Concepts
Oracle WebLogic Server Basic ConceptsJames Bayer
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React NativeSambhu Lakshmanan
 
Building a data warehouse with Pentaho and Docker
Building a data warehouse with Pentaho and DockerBuilding a data warehouse with Pentaho and Docker
Building a data warehouse with Pentaho and DockerWellington Marinho
 
Weblogic application server
Weblogic application serverWeblogic application server
Weblogic application serverAnuj Tomar
 
Monitoring with Prometheus
Monitoring with PrometheusMonitoring with Prometheus
Monitoring with PrometheusShiao-An Yuan
 
Laravel introduction
Laravel introductionLaravel introduction
Laravel introductionSimon Funk
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How ToJi-Woong Choi
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud VMware Tanzu
 
Android's HIDL: Treble in the HAL
Android's HIDL: Treble in the HALAndroid's HIDL: Treble in the HAL
Android's HIDL: Treble in the HALOpersys inc.
 
Kotlin vs Java | Edureka
Kotlin vs Java | EdurekaKotlin vs Java | Edureka
Kotlin vs Java | EdurekaEdureka!
 
Introduction to Apache NiFi 1.11.4
Introduction to Apache NiFi 1.11.4Introduction to Apache NiFi 1.11.4
Introduction to Apache NiFi 1.11.4Timothy Spann
 
The Apollo and GraphQL Stack
The Apollo and GraphQL StackThe Apollo and GraphQL Stack
The Apollo and GraphQL StackSashko Stubailo
 

What's hot (20)

Laravel
LaravelLaravel
Laravel
 
Introduction Node.js
Introduction Node.jsIntroduction Node.js
Introduction Node.js
 
Oracle WebLogic Server Basic Concepts
Oracle WebLogic Server Basic ConceptsOracle WebLogic Server Basic Concepts
Oracle WebLogic Server Basic Concepts
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Building a data warehouse with Pentaho and Docker
Building a data warehouse with Pentaho and DockerBuilding a data warehouse with Pentaho and Docker
Building a data warehouse with Pentaho and Docker
 
Weblogic application server
Weblogic application serverWeblogic application server
Weblogic application server
 
Apache NiFi Crash Course Intro
Apache NiFi Crash Course IntroApache NiFi Crash Course Intro
Apache NiFi Crash Course Intro
 
VSS_Final
VSS_FinalVSS_Final
VSS_Final
 
Monitoring with Prometheus
Monitoring with PrometheusMonitoring with Prometheus
Monitoring with Prometheus
 
Laravel introduction
Laravel introductionLaravel introduction
Laravel introduction
 
Go lang
Go langGo lang
Go lang
 
How browser work
How browser workHow browser work
How browser work
 
[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To[오픈소스컨설팅]Tomcat6&7 How To
[오픈소스컨설팅]Tomcat6&7 How To
 
DOT Net overview
DOT Net overviewDOT Net overview
DOT Net overview
 
Introduction to Spring Cloud
Introduction to Spring Cloud           Introduction to Spring Cloud
Introduction to Spring Cloud
 
Android.ppt
Android.pptAndroid.ppt
Android.ppt
 
Android's HIDL: Treble in the HAL
Android's HIDL: Treble in the HALAndroid's HIDL: Treble in the HAL
Android's HIDL: Treble in the HAL
 
Kotlin vs Java | Edureka
Kotlin vs Java | EdurekaKotlin vs Java | Edureka
Kotlin vs Java | Edureka
 
Introduction to Apache NiFi 1.11.4
Introduction to Apache NiFi 1.11.4Introduction to Apache NiFi 1.11.4
Introduction to Apache NiFi 1.11.4
 
The Apollo and GraphQL Stack
The Apollo and GraphQL StackThe Apollo and GraphQL Stack
The Apollo and GraphQL Stack
 

Viewers also liked

Planeaciones de la primera semana
Planeaciones de la  primera semanaPlaneaciones de la  primera semana
Planeaciones de la primera semanadaisy gonzalez
 
Trinity Daily Dec 8, 2016
Trinity Daily Dec 8, 2016Trinity Daily Dec 8, 2016
Trinity Daily Dec 8, 2016Arun Surendran
 
Informe de evidencias de la primera semana
Informe de evidencias  de la primera semanaInforme de evidencias  de la primera semana
Informe de evidencias de la primera semanadaisy gonzalez
 
Powerpoint afscheid 6de leerjaar 2015 - 2016
Powerpoint afscheid 6de leerjaar 2015 - 2016Powerpoint afscheid 6de leerjaar 2015 - 2016
Powerpoint afscheid 6de leerjaar 2015 - 2016Sven De Wilde
 
1 павлова т.л. презентація
1 павлова т.л.  презентація1 павлова т.л.  презентація
1 павлова т.л. презентаціяschool11_dp
 
Trinity Daily Dec 9, 2016
Trinity Daily Dec 9, 2016Trinity Daily Dec 9, 2016
Trinity Daily Dec 9, 2016Arun Surendran
 
REACTORES NUCLEARES DE INVESTIGACION
REACTORES NUCLEARES DE INVESTIGACIONREACTORES NUCLEARES DE INVESTIGACION
REACTORES NUCLEARES DE INVESTIGACIONZuniga Agustin
 
Planeación segunda semana marzo de la primera jornada
Planeación segunda semana marzo de la primera jornada Planeación segunda semana marzo de la primera jornada
Planeación segunda semana marzo de la primera jornada daisy gonzalez
 
3. una escuela-para-cada-estudiante
3. una escuela-para-cada-estudiante3. una escuela-para-cada-estudiante
3. una escuela-para-cada-estudianteEileen Crespo Pineda
 
شرح هفت شهر عشق عطار نیشابوری
شرح هفت شهر عشق عطار نیشابوریشرح هفت شهر عشق عطار نیشابوری
شرح هفت شهر عشق عطار نیشابوریFarid Kamali
 
شفایافته گان با تغذیه طبیعی خام گیاهی
شفایافته گان با تغذیه طبیعی خام گیاهیشفایافته گان با تغذیه طبیعی خام گیاهی
شفایافته گان با تغذیه طبیعی خام گیاهیFarid Kamali
 
Chinse made easy for kids
Chinse made easy for kidsChinse made easy for kids
Chinse made easy for kidsnicolezhang
 
Ableitung in der deutschen Gegenwartssprache - Ein Überblick
Ableitung in der deutschen Gegenwartssprache - Ein ÜberblickAbleitung in der deutschen Gegenwartssprache - Ein Überblick
Ableitung in der deutschen Gegenwartssprache - Ein ÜberblickJelena Kostic-Tomovic
 
Revista voz ativa sinpromg 1ª ed março 2016
Revista voz ativa sinpromg 1ª ed março 2016Revista voz ativa sinpromg 1ª ed março 2016
Revista voz ativa sinpromg 1ª ed março 2016Anderson Ramos
 

Viewers also liked (17)

Planeaciones de la primera semana
Planeaciones de la  primera semanaPlaneaciones de la  primera semana
Planeaciones de la primera semana
 
Bronze Listing Survey
Bronze Listing SurveyBronze Listing Survey
Bronze Listing Survey
 
Trinity Daily Dec 8, 2016
Trinity Daily Dec 8, 2016Trinity Daily Dec 8, 2016
Trinity Daily Dec 8, 2016
 
Informe de evidencias de la primera semana
Informe de evidencias  de la primera semanaInforme de evidencias  de la primera semana
Informe de evidencias de la primera semana
 
Powerpoint afscheid 6de leerjaar 2015 - 2016
Powerpoint afscheid 6de leerjaar 2015 - 2016Powerpoint afscheid 6de leerjaar 2015 - 2016
Powerpoint afscheid 6de leerjaar 2015 - 2016
 
1 павлова т.л. презентація
1 павлова т.л.  презентація1 павлова т.л.  презентація
1 павлова т.л. презентація
 
Trinity Daily Dec 9, 2016
Trinity Daily Dec 9, 2016Trinity Daily Dec 9, 2016
Trinity Daily Dec 9, 2016
 
REACTORES NUCLEARES DE INVESTIGACION
REACTORES NUCLEARES DE INVESTIGACIONREACTORES NUCLEARES DE INVESTIGACION
REACTORES NUCLEARES DE INVESTIGACION
 
Planeación segunda semana marzo de la primera jornada
Planeación segunda semana marzo de la primera jornada Planeación segunda semana marzo de la primera jornada
Planeación segunda semana marzo de la primera jornada
 
Eразъм+ обща
Eразъм+ общаEразъм+ обща
Eразъм+ обща
 
3. una escuela-para-cada-estudiante
3. una escuela-para-cada-estudiante3. una escuela-para-cada-estudiante
3. una escuela-para-cada-estudiante
 
شرح هفت شهر عشق عطار نیشابوری
شرح هفت شهر عشق عطار نیشابوریشرح هفت شهر عشق عطار نیشابوری
شرح هفت شهر عشق عطار نیشابوری
 
شفایافته گان با تغذیه طبیعی خام گیاهی
شفایافته گان با تغذیه طبیعی خام گیاهیشفایافته گان با تغذیه طبیعی خام گیاهی
شفایافته گان با تغذیه طبیعی خام گیاهی
 
rushi
rushirushi
rushi
 
Chinse made easy for kids
Chinse made easy for kidsChinse made easy for kids
Chinse made easy for kids
 
Ableitung in der deutschen Gegenwartssprache - Ein Überblick
Ableitung in der deutschen Gegenwartssprache - Ein ÜberblickAbleitung in der deutschen Gegenwartssprache - Ein Überblick
Ableitung in der deutschen Gegenwartssprache - Ein Überblick
 
Revista voz ativa sinpromg 1ª ed março 2016
Revista voz ativa sinpromg 1ª ed março 2016Revista voz ativa sinpromg 1ª ed março 2016
Revista voz ativa sinpromg 1ª ed março 2016
 

Similar to IPC: AIDL is sexy, not a curse

That’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryThat’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryMichael Galpin
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developersPavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best PracticesYekmer Simsek
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than WebHeiko Behrens
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql JOYITAKUNDU1
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and MonoidsHugo Gävert
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsAlfonso Peletier
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryAlexandre Morgaut
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneDroidConTLV
 
There's more than web
There's more than webThere's more than web
There's more than webMatt Evans
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 

Similar to IPC: AIDL is sexy, not a curse (20)

That’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your BatteryThat’s My App - Running in Your Background - Draining Your Battery
That’s My App - Running in Your Background - Draining Your Battery
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Android Best Practices
Android Best PracticesAndroid Best Practices
Android Best Practices
 
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Webbeyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
beyond tellerrand: Mobile Apps with JavaScript – There's More Than Web
 
Why realm?
Why realm?Why realm?
Why realm?
 
Android wearpp
Android wearppAndroid wearpp
Android wearpp
 
Java and xml
Java and xmlJava and xml
Java and xml
 
code for quiz in my sql
code for quiz  in my sql code for quiz  in my sql
code for quiz in my sql
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Introduction to Scalding and Monoids
Introduction to Scalding and MonoidsIntroduction to Scalding and Monoids
Introduction to Scalding and Monoids
 
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic LabsTypeScript - All you ever wanted to know - Tech Talk by Epic Labs
TypeScript - All you ever wanted to know - Tech Talk by Epic Labs
 
Android For All The Things
Android For All The ThingsAndroid For All The Things
Android For All The Things
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
NoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love StoryNoSQL and JavaScript: a Love Story
NoSQL and JavaScript: a Love Story
 
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGeneBang-Bang, you have been hacked - Yonatan Levin, KolGene
Bang-Bang, you have been hacked - Yonatan Levin, KolGene
 
There's more than web
There's more than webThere's more than web
There's more than web
 
Testing in android
Testing in androidTesting in android
Testing in android
 

More from Yonatan Levin

Knock, knock, who is there? Doze.
Knock, knock, who is there? Doze.Knock, knock, who is there? Doze.
Knock, knock, who is there? Doze.Yonatan Levin
 
Android Performance #4: Network
Android Performance #4: NetworkAndroid Performance #4: Network
Android Performance #4: NetworkYonatan Levin
 
Performance #1: Memory
Performance #1: MemoryPerformance #1: Memory
Performance #1: MemoryYonatan Levin
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeedYonatan Levin
 
Mobile UI: Fruit or Delicious sweets
Mobile UI: Fruit or Delicious sweetsMobile UI: Fruit or Delicious sweets
Mobile UI: Fruit or Delicious sweetsYonatan Levin
 
Ipc: aidl sexy, not a curse
Ipc: aidl sexy, not a curseIpc: aidl sexy, not a curse
Ipc: aidl sexy, not a curseYonatan Levin
 
How to create Great App
How to create Great AppHow to create Great App
How to create Great AppYonatan Levin
 
What's new in android M(6.0)
What's new in android M(6.0)What's new in android M(6.0)
What's new in android M(6.0)Yonatan Levin
 
IPC: AIDL is not a curse
IPC: AIDL is not a curseIPC: AIDL is not a curse
IPC: AIDL is not a curseYonatan Levin
 
Fragments, the love story
Fragments, the love storyFragments, the love story
Fragments, the love storyYonatan Levin
 
Lecture #3: Android Academy Study Jam
Lecture #3: Android Academy Study JamLecture #3: Android Academy Study Jam
Lecture #3: Android Academy Study JamYonatan Levin
 
Lecture #1 intro,setup, new project, sunshine
Lecture #1   intro,setup, new project, sunshineLecture #1   intro,setup, new project, sunshine
Lecture #1 intro,setup, new project, sunshineYonatan Levin
 

More from Yonatan Levin (15)

Knock, knock, who is there? Doze.
Knock, knock, who is there? Doze.Knock, knock, who is there? Doze.
Knock, knock, who is there? Doze.
 
Android Performance #4: Network
Android Performance #4: NetworkAndroid Performance #4: Network
Android Performance #4: Network
 
Performance #1: Memory
Performance #1: MemoryPerformance #1: Memory
Performance #1: Memory
 
A friend in need - A JS indeed
A friend in need - A JS indeedA friend in need - A JS indeed
A friend in need - A JS indeed
 
Mobile UI: Fruit or Delicious sweets
Mobile UI: Fruit or Delicious sweetsMobile UI: Fruit or Delicious sweets
Mobile UI: Fruit or Delicious sweets
 
Ipc: aidl sexy, not a curse
Ipc: aidl sexy, not a curseIpc: aidl sexy, not a curse
Ipc: aidl sexy, not a curse
 
How to create Great App
How to create Great AppHow to create Great App
How to create Great App
 
Mobile world
Mobile worldMobile world
Mobile world
 
Data binding
Data bindingData binding
Data binding
 
What's new in android M(6.0)
What's new in android M(6.0)What's new in android M(6.0)
What's new in android M(6.0)
 
Performance
PerformancePerformance
Performance
 
IPC: AIDL is not a curse
IPC: AIDL is not a curseIPC: AIDL is not a curse
IPC: AIDL is not a curse
 
Fragments, the love story
Fragments, the love storyFragments, the love story
Fragments, the love story
 
Lecture #3: Android Academy Study Jam
Lecture #3: Android Academy Study JamLecture #3: Android Academy Study Jam
Lecture #3: Android Academy Study Jam
 
Lecture #1 intro,setup, new project, sunshine
Lecture #1   intro,setup, new project, sunshineLecture #1   intro,setup, new project, sunshine
Lecture #1 intro,setup, new project, sunshine
 

IPC: AIDL is sexy, not a curse

  • 1. Build a sustainable app with an IPC mechanism IPC: AIDL is Sexy, not a curse
  • 3. > 10M users Ruby, Golang, Python, Android, iOS 52 cities
  • 5. What are we going to do?
  • 6. Learn how to talk ➔Became best fellows with IPC ➔Best friends with Binder ➔Fall in love with AIDL
  • 7. Goal: Make our app run smooth in the background while performing multiple long tasks (like playing music) unrelated to the UI
  • 8.
  • 9. DarthVaderActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.darth_vader_activity); findViewById(R.id.iv_dva_build_death_star).setOnClickListener(this); findViewById(R.id.iv_dva_interact_with_luke).setOnClickListener(this); }
  • 11. Why separate process? ● GC not affecting your app ● Crashing not affecting UI ● Less chance to be killed: ○ Process serving others has at least the ranking of those it serve ○ Process with Service > Process with Background activities ● New Heap Space ● Smaller cold start + resource efficiency ● Because we can! :)
  • 12. Why and when not? ●If you don’t have driver licenses ●Memory leaks ●Two process ●Keep it simple, stupid
  • 14. IPC? Inter-process communication (IPC) is a framework for the exchange of signals and data across multiple processes
  • 18. Benefit for free ●Thread migration ●Identifying senders to receivers ●Unique object-mapping across process ●AIDL!!!! ●Bult-in support for marshalling ●Local execution mode (no IPC) if same process
  • 19. We are already using binder today ●LifeCycle callbacks (onResume, OnDestroy) invoked by ActivityManagerService ●Intents ●Content Provider
  • 20. 1 IPC using Intent git checkout IPCwithIntent
  • 21. DarthVaderActivity @Override public void onClick(View v) { Intent intent = new Intent(this, EmpireService.class); switch (v.getId()) { case R.id.iv_dva_build_death_star: intent.putExtra(COMMAND_TYPE, EmpireService.EmpireServiceCommands.BUILD_DEATH_STAR); break; case R.id.iv_dva_interact_with_luke: intent.putExtra(COMMAND_TYPE, EmpireService.EmpireServiceCommands.FIND_LUKE); break; } mStartedCommandTime = System.currentTimeMillis(); startService(intent); }
  • 22. DarthVaderActivity public class EmpireServiceReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.d(TAG,"Time took: " +String.valueOf(System.currentTimeMillis()- mStartedCommandTime)); Toast.makeText(DarthVaderActivity.this, "Death Star deployed and ready for your command, my lord", Toast.LENGTH_LONG).show(); } }
  • 23. EmpireService public int onStartCommand(Intent intent, int flags, int startId) { EmpireServiceCommands command = (EmpireServiceCommands) intent.getExtras() .get(COMMAND_TYPE); switch (command) { case BUILD_DEATH_STAR: ..do some hard work... Intent jobDoneIntent = new Intent(EMPIRE_SERVICE_ACTION); jobDoneIntent.putExtra("result", new DeathStar(270000, 270000, "THIS IS THE BIG GUN")); sendBroadcast(jobDoneIntent); break; case FIND_LUKE: break; } stopSelf(); return START_NOT_STICKY; }
  • 24. Pain? Not really OOP Async only Loosely-defined Not so fast High Level Abstraction of Binder
  • 25. 2 IPC using Messenger git checkout IPCwithMessenger
  • 26. A reference to a Handler that can be sent to a remote process via an Intent Messages sent by the remote process via the messenger are delivered to the local handler Relatively fast Overview
  • 27. DarthVaderActivity public void onClick(View v) { Intent intent = new Intent(this, EmpireService.class); Messenger messenger = new Messenger(new DarthVaderHandler(this)); intent.putExtra("ImperialMessenger", messenger); switch (v.getId()) { case R.id.iv_dva_build_death_star: intent.putExtra("Command type", EmpireService.EmpireServiceCommands.BUILD_DEATH_STAR); break; case R.id.iv_dva_interact_with_luke: intent.putExtra("Command type", EmpireService.EmpireServiceCommands.FIND_LUKE); break; } startService(intent); }
  • 28. DarthVaderActivity private static class DarthVaderHandler extends Handler { private final WeakReference<DarthVaderActivity> clientRef; public DarthVaderHandler(DarthVaderActivity client) { this.clientRef = new WeakReference<>(client); } ...//Handle message }
  • 29. DarthVaderActivity private static class DarthVaderHandler extends Handler { @Override public void handleMessage(Message msg) { Bundle data = msg.getData(); DarthVaderActivity client = clientRef.get(); if (client != null && msg.what == EmpireService.CALLBACK_MSG && data != null) { Toast.makeText(client, "Death Star deployed and ready for your command, my lord", Toast.LENGTH_LONG).show(); } } }
  • 30. EmpireService public int onStartCommand(Intent intent, int flags, int startId) { Messenger messenger = intent.getParcelableExtra("ImperialMessenger"); EmpireServiceCommands command = (EmpireServiceCommands) intent.getExtras() .get("Command type"); … more code coming...
  • 31. EmpireService switch (command) { case BUILD_DEATH_STAR: ..do some hard work... if (messenger != null) { Message message = Message.obtain(); message.what = CALLBACK_MSG; Bundle data = new Bundle(1); data.putParcelable("result", new DeathStar(270000, 270000, "THIS IS THE BIG GUN")); message.setData(data); try { messenger.send(message); } catch (RemoteException e) { e.printStackTrace(); } } break;
  • 32. But what if... We want sync calls? Full OOP Business Transparent
  • 33. 3 IPC using AIDL git checkout IPCwithAIDL
  • 34. Android Interface Definition Language (AIDL) Our business operation on top of Binder object Java-like interface Defined in a separate .aidl file AIDL Generate code of real java interface
  • 35. .AIDL interface interface IStarWars { String buildDeathStar(out DeathStar deathStar); oneway void findLuke(in IEmpireServiceResponseListener listener); }
  • 36. DeathStar.aidl package com.academy.android.aidlserviceexample; // Declare DeathStar so AIDL can find it and knows that it implements // the parcelable protocol. parcelable DeathStar;
  • 38. IStarWars.Stub /** Local-side IPC implementation stub class. */ public static abstract class Stub extends android.os.Binder implements com.academy.android.aidlserviceexample.IStarWars { @Override public java.lang.String buildDeathStar( com.academy.android.aidlserviceexample.DeathStar deathStar) throws android.os.RemoteException { android.os.Parcel _data = android.os.Parcel.obtain(); android.os.Parcel _reply = android.os.Parcel.obtain(); java.lang.String _result; try { _data.writeInterfaceToken(DESCRIPTOR); mRemote.transact(Stub.TRANSACTION_buildDeathStar, _data, _reply, 0); … not really necessary to dig in
  • 39. Interface directional flag in means that the object is transferred from client to service and only used for inputs. If any changes are made to the bar object in the service then they won’t reflect in the client. out indicates that the object has no relevant data and will be populated by the service and returned as a response. inout means that the data gets copied, i.e., if any changes are made to bar in the service then that’ll also reflect in the client’s bar object.
  • 40. AIDL Data Types All primitives and arrays of primitives FileDescriptor Serializable/Parcelable**** Map Bundle List SparseArray
  • 41. Sync Call - Death Star Let the fun begin!
  • 42. IStarWarsImplementation public class IStarWarsImplementation extends IStarWars.Stub { public String buildDeathStar(DeathStar deathStar) throws RemoteException { ...doing hard work.. deathStar.setBFG("BIG GUN IS VERY VERY"); deathStar.setHeight(270000); deathStar.setWidth(270000); return "Death Star deployed and ready for your command, my lord"; } … other interface methods
  • 43. EmpireService public class EmpireService extends Service { private IStarWarsImplementation service; @Override public void onCreate() { super.onCreate(); service = new IStarWarsImplementation(); }
  • 44. EmpireService @Override public IBinder onBind(Intent intent) { return service; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { this.service = null; super.onDestroy(); }
  • 45. DarthVaderActivity public class DarthVaderActivity extends Activity implements ServiceConnection { @Override protected void onResume() { super.onResume(); final boolean isServiceBounded = super.bindService(new Intent(this, EmpireService.class), this, BIND_AUTO_CREATE); if (!isServiceBounded) { Log.w(TAG, "Failed to bind to service"); } } … more methods
  • 46. DarthVaderActivity @Override public void onServiceConnected(ComponentName name, IBinder service) { this.service = IStarWars.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { this.service = null; }
  • 47. DarthVaderActivity @Override public void onClick(View v) { try { switch (v.getId()) { case R.id.iv_dva_build_death_star: DeathStar deathStar = new DeathStar(); final String reply = service.buildDeathStar(deathStar); String buildDeathStar = String .format("%s and it have %s", reply, deathStar.getBFG()); Toast.makeText(this, buildDeathStar, Toast.LENGTH_LONG).show(); break; } } catch (RemoteException e) { e.printStackTrace(); }
  • 48. ASync Call - Find a luke
  • 49. .AIDL interface interface IStarWars { String buildDeathStar(out DeathStar deathStar); oneway void findLuke(in IEmpireServiceResponseListener listener); } interface IEmpireServiceResponseListener { void onResponse(String response); }
  • 50. IStarWarsImplementation ...other AIDL interface implementation methods @Override public void findLuke(IEmpireServiceResponseListener listener) throws RemoteException { ..Doing very hard job through couple episodes… listener.onResponse("I'm your father, Luke!"); }
  • 51. DarthVaderActivity IEmpireServiceResponseListener.Stub mListener = new IEmpireServiceResponseListener.Stub() { @Override public void onResponse(final String response) throws RemoteException { //Other process. We should run on UI Thread in order to interact with UI mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(DarthVaderActivity.this, response, Toast.LENGTH_LONG) .show(); } }); } };
  • 52. DarthVaderActivity @Override public void onClick(View v) { try { switch (v.getId()) { case R.id.iv_dva_interact_with_luke: service.findLuke(mListener); break; } } catch (RemoteException e) { e.printStackTrace(); } }
  • 54. What did we get? Services running on separate process Easy expandable communication Great performance Fun :)