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

Practical IPC

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Practical IPC

Avatar for Keishin Yokomaku

Keishin Yokomaku

November 22, 2016
Tweet

More Decks by Keishin Yokomaku

Other Decks in Technology

Transcript

  1. Practical IPC About Me ▸ Keishin Yokomaku ▸ Drivemode, Inc.

    / Principal Engineer ▸ KeithYokoma: GitHub / Twitter / Qiita / Tumblr / Stack Overflow ▸ Books: Mobile App Dev Guide / Android Academia / Grimoire of Android ▸ Fun: Gymnastics / Cycling / Photography / Motorsport ▸ Today’s Quote: “Power is everything.” 2
  2. Practical IPC IPC ͕࢖ΘΕ͍ͯΔ৔ॴ ▸ PackageManager ▸ e.g. PackageManager ͕ಈ͍͍ͯΔϓϩηεʹର͢Δ໰͍߹Θͤ

    ▸ Intent ▸ e.g. ϥϯνϟʔ͔ΒΞϓϦͷىಈ ▸ android.media.session, android.media.browser ▸ Android Auto ༻ͷΦʔσΟΦΞϓϦ޲͚ϑϨʔϜϫʔΫ 8
  3. Practical IPC AIDL ▸ Android Interface Definition Language ▸ Java

    ʹࣅͨจ๏Λ࣋ͬͨಛผͳݴޠ ▸ ΠϯλϑΣʔεΛఆٛ͢ΔͨΊʹ࢖͏ ▸ ࣮ࡍͷॲཧ͸ Java Ͱهड़͢Δ ▸ aidl ઐ༻ͷσΟϨΫτϦʹೖΕ͓ͯ͘ 10
  4. Practical IPC ίϯύΠϧΤϥʔʹͳΔ AIDL ͷهड़ྫ 1 package com.github.keithyokoma.aidl; interface SampleAidl

    { String getSomething(int value); String getSomething(int value, boolean flag); } 12 Φʔόʔϩʔυ͸Ͱ͖ͳ͍
  5. Practical IPC ίϯύΠϧΤϥʔʹͳΔ AIDL ͷهड़ྫ 2 package com.github.keithyokoma.aidl; interface SampleAidl

    { String getSomething(int value); void doSomething(CustomObject object); } 13 ϓϦϛςΟϒܕɾStringܕɾҰ෦ͷίϨΫγϣϯܕҎ֎ͷܕ͸ಛผʹએݴ͠ͳ͍ݶΓ࢖͑ͳ͍
  6. Practical IPC ಠࣗΫϥεΛ IPC Ͱ࢖͏ͨΊͷ parcelable Ωʔϫʔυ package com.github.keithyokoma.aidl; interface

    SampleAidl { String getSomething(int value); void doSomething(CustomObject object); } parcelable CustomObject; 14 CustomObject ͸ Parcelable Λ࣮૷γͨΫϥεͰ͋Δ͜ͱΛ໌ࣔ
  7. Practical IPC ඇಉظॲཧͷͨΊͷ AIDL ͷه๏ package com.github.keithyokoma.aidl; oneway interface SampleAidl

    { String getSomething(int value); } 15 oneway Ωʔϫʔυ͕ͭ͘ͱɺϝιουݺͼग़͕͠ଈ࠲ʹฦ٫͞Ε݁Ռ͸ඇಉظʹฦͬͯ͘Δ
  8. Practical IPC AIDL Λ࢖ͬͨ IPC ͷਤ 17 Client Server Proxy

    Stub IBinder AIDL Λॻ͍ͯϏϧυ͢Δͱࣗಈੜ੒͞ΕΔ
  9. Practical IPC AIDL Λ࢖ͬͨ IPC ͷਤ 18 Client Server Proxy

    Stub IBinder ࣮ࡍʹ͸libbinder ΍ binder Ϟδϡʔϧ౳ͷॲཧ͕ؒʹ͋Δ
  10. Practical IPC Service ͷ࣮૷1 public class MyService extends Service {

    private final SampleAidl.Stub mStub = new SampleAidl.Stub() { @Override public String getSomething(int value) { return “Hello World!”; } } @Nullable @Override public IBinder onBind(Intent intent) { return mStub; } } 19
  11. Practical IPC Service ͷ࣮૷1 public class MyService extends Service {

    private final SampleAidl.Stub mStub = new SampleAidl.Stub() { @Override public String getSomething(int value) { return “Hello World!”; } } @Nullable @Override public IBinder onBind(Intent intent) { return mStub; } } 20
  12. Practical IPC Service ͷ࣮૷1 public class MyService extends Service {

    private final SampleAidl.Stub mStub = new SampleAidl.Stub() { @Override public String getSomething(int value) { return “Hello World!”; } } @Nullable @Override public IBinder onBind(Intent intent) { return mStub; } } 21
  13. Practical IPC Service ͷ࣮૷2 <manifest> <application> <service android:name=“.MyService” android:exported=“true” android:enabled=“true”>

    <intent-filter> <action android:name=“com.example.SampleAidl.ACTION_CONNECT” /> </intent-filter> </service> </application> </manifest> 22
  14. Practical IPC Service ͷ࣮૷2 <manifest> <application> <service android:name=“.MyService” android:exported=“true” android:enabled=“true”>

    <intent-filter> <action android:name=“com.example.SampleAidl.ACTION_CONNECT” /> </intent-filter> </service> </application> </manifest> 23
  15. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷1 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = SampleAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mService = null; } } private SampleAidl mService; } 24
  16. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷1 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = SampleAidl.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { mService = null; } } private SampleAidl mService; } 25
  17. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷2 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = // …… private SampleAidl mService; public void onClickStartConnection(View view) { Intent intent = new Intent(“com.sample.SampleAidl.ACTION_CONNECT”); bindService(intent, mConnection, BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); } } 26
  18. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷2 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = // …… private SampleAidl mService; public void onClickStartConnection(View view) { Intent intent = new Intent(“com.sample.SampleAidl.ACTION_CONNECT”); bindService(intent, mConnection, BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); } } 27
  19. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷3 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = // …… private SampleAidl mService; public void onClickGetSomething() { try { Toast.makeText(getApplicationContext(), mService.getSomething(1), Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { // something went wrong } } } 28
  20. Practical IPC Service Λݺͼग़͢ଆͷ࣮૷3 public class MyActivity extends Activity {

    private final ServiceConnection mConnection = // …… private SampleAidl mService; public void onClickGetSomething() { try { Toast.makeText(getApplicationContext(), mService.getSomething(1), Toast.LENGTH_SHORT).show(); } catch (RemoteException e) { // something went wrong } } } 29
  21. Practical IPC ͳͥ IPC Λ࢖͏ͷ͔ ▸ ଞͷΞϓϦͱόοΫάϥ΢ϯυͰ࿈ܞ͍ͨ͠ ▸ e.g. ଞͷΞϓϦʹ௚઀σʔλΛૹΓࠐΜͰԿΒ͔ͷॲཧΛͯ͠΋Β͍͍ͨ

    ▸ e.g. ଞͷΞϓϦʹσʔλͷऔಘΛ୅ཧͯ͠΋Β͍͍ͨ ▸ e.g. ଞͷΞϓϦ͕͍࣋ͬͯΔίϯςϯπΛૢ࡞͍ͨ͠ ▸ etc… 30
  22. Practical IPC ͳͥ IPC Λ࢖͏ͷ͔ ▸ ྑ͍ͱ͜Ζ ▸ Activity ͷΈͳΒͣɺৗறܕ

    Service Ͱ΋࢖͑Δ ▸ όΠϯυҎ֎Ͱ Intent (broadcast ؚΉ) ͷ࢓૊ΈΛհ͞ͳ͍ͷͰಈ࡞΋͸΍͍ ▸ ਏ͍ͱ͜Ζ ▸ ؅ཧίετ͕͔͞Ή(֎෦ެ։લఏͳͷͰόʔδϣϯ؅ཧ͕ඞཁɾޙड़) ▸ ฼؋ΞϓϦ͕ແ͍ͱ໾ʹཱͨͳ͍ 31
  23. Practical IPC IPC ͷ࢖͍ॴ ▸ SDK ͱͯ͠ΞϓϦͷಛఆͷػೳɾAPI Λެ։͢Δ ▸ e.g.

    ΦʔσΟΦͷ࠶ੜίϯτϩʔϧػೳΛ AIDL Ͱఆٛ͢Δ ▸ e.g. AIDL ܦ༝ͰΞϓϦʹΞυΦϯػೳΛ௥Ճ͢Δ ▸ etc… 32
  24. Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ڐՄͨ͠௨৴૬खͱ͚ͩ IPC ͍ͨ͠ ▸ Կ΋͠ͳ͍ͱ୭ͱͰ΋

    IPC Ͱ͖ͯ͠·͏ ▸ ηΩϡϦςΟϦεΫ ▸ ઀ଓ࣌ʹ୭͕௨৴ΛࢼΈ͍ͯΔ͔ݕূ͢Δ ▸ μϝͳ૬खͱͷίωΫγϣϯ͸མͱ͢ 34
  25. Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ݕূʹ࢖͏৘ใ ▸ ύοέʔδ໊ ▸ ॺ໊ͷϋογϡ

    ▸ Android Auto ޲͚ API ͷ MediaBrowserService ͕ྑ͍ྫ ▸ xml ʹڐՄ͢Δύοέʔδ໊ͱॺ໊ͷϋογϡͷҰཡΛ͓࣋ͬͯ͘ ▸ http://bit.ly/2gdkUJP 35
  26. Practical IPC TransactionTooLargeException ▸ ϓϩηεؒ௨৴Ͱ࢖͑ΔϝϞϦۭؒͷ੍ݶΛ௒͑ͨ ▸ 1ϓϩηεʹׂΓ౰ͯΒΕΔϓϩηεؒ௨৴༻ͷϝϞϦۭؒ͸1mB ▸ ճආࡦ ▸

    ಉ࣌ʹͨ͘͞Μϓϩηεؒ௨৴͠ͳ͍ ▸ Bitmap ͳͲڊେͳσʔλΛϓϩηεؒ௨৴ʹͷͤͳ͍ ▸ Ͳ͏ͯ͠΋ Bitmap Λ࢖͏ͱ͖͸ɺBitmap ͷαΠζΛࢦఆͰ͖ΔΑ͏ʹ͢Δ 38
  27. Practical IPC Don’t interface RemoteService { void setBitmap(in Bitmap image);

    } 39 Do interface RemoteService { void setBitmap(in Uri imageUri); }
  28. Practical IPC BadParcelableException 41 ▸ ޓ׵ੑͷͳ͍ Parcelable Λड͚औͬͨ ▸ Ϋϥεϩʔμͷҧ͍ΛߟྀʹೖΕΑ͏

    ▸ ϑΟʔϧυͷ௥Ճɾ࡟আ͸৻ॏʹʢSerializableΑΓ͸΍͍͞͠ʣ ▸ ճආࡦ ▸ ΫϥεϩʔμΛஔ͖׵͑Δ
  29. Practical IPC DeadObjectException ▸ ࢮΜͰ͍Δϓϩηεʹ௨৴ΛࢼΈͨ ▸ ࢮମऽΓɺμϝઈର ▸ ճආࡦ ▸

    IBinder.DeathRecipient ΍ ServiceConnection Ͱࢮ׆؂ࢹ ▸ SDK ͱͯ͠ϥοϓͨ͠ΫϥεΛఏڙ͢Δ৔߹ɺࢮΜͩ͜ͱΛίʔϧόοΫ͢ΔΠ ϯλϑΣʔεΛผ్༻ҙ͢ΔͱΑ͍ 43
  30. Practical IPC DeadObjectException private RemoteService mService; private boolean mIsBound; private

    ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName component, IBinder service) { mService = ((RemoteService.Binder) service).getService(); mIsBound = true; } @Override public void onServiceDisconnected() { mIsBound = false; } } 44
  31. Practical IPC DeadObjectException public static abstract class Callback implements IBinder.DeathRecipient

    { @Override public void binderDied() { onDestroy(); } public abstract void onDestroy(); } private IBinder mBinder; public void registerCallback(Callback callback) { mBinder.asBinder().linkToDeath(callback, 0); } public void unregisterCallback(Callback callback) { mBinder.asBinder().unlinkToDeath(callback, 0); } 45
  32. Practical IPC AIDL ͷόʔδϣϯ؅ཧ ▸ ϝιουΛΦʔόʔϩʔυ͍ͨ͠ ▸ ෆՄೳͳͷͰผ໊ʹ͢Δ͔͠ͳ͍ ▸ όουϊ΢ϋ΢Λ࢖͏(ޙड़)

    ▸ Parcelable Λมߋ͍ͨ͠ ▸ ϑΟʔϧυͷ௥Ճͷͱ͖ɺParcel ͔Βͷ෮ؼ΍ॻ͖ࠐΈͷॱ൪͸࠷ޙʹ௥Ճ 46
  33. Practical IPC AIDL ͷόʔδϣϯ؅ཧʹ͓͚Δόουϊ΢ϋ΢ ▸ ΦʔόʔϩʔυͰ͖ͳ͍໰୊ ▸ ࣮͸ Service ͷ࣮૷ʹϝιου͕͋Γ͑͢͞Ε͹Φʔόʔϩʔυ͸Ͱ͖Δ

    ▸ e.g. ݺͼग़͠ઌͷ AIDL Ͱ hoge() ϝιουΛ hoge(int) ʹมߋɺͨͩ͠ Service ͷ࣮૷ʹ͸ hoge() ΋࢒ͯ͋͠Δ => ݺͼग़͠ݩͷΞϓϦͷ AIDL ʹ͸ hoge() ͔͠ͳͯ͘΋ hoge() ͸ͪΌΜͱݺ΂Δ 47
  34. Practical IPC ·ͱΊ ▸ AIDL ͷ࢖͍ॴ ▸ ଞͷΞϓϦʹࣗ෼ͷΞϓϦͷ΋ͭػೳΛެ։͢Δ ▸ ΞυΦϯ௥Ճɺσʔλͷऔಘɾૹ৴ɺίϯςϯπͷૢ࡞ͳͲ

    ▸ SDK ͱͯ͠഑෍ ▸ Intent ͷΑ͏ͳதؒϨΠϠ͕ͳ͘ͳΔͷͰಈ࡞͸଎͍ ▸ ίʔϧόοΫ౳Λ༻ҙͯ͠։ൃऀϑϨϯυϦʔʹ͢Δ 50
  35. Practical IPC ·ͱΊ ▸ AIDL ͷ੍໿ ▸ ΦʔόʔϩʔυෆՄ ▸ ϓϦϛςΟϒܕɺStringܕɺҰ෦ίϨΫγϣϯܕҎ֎͸ParcelableΛ࣮૷

    ▸ Parcelable ͷ੍໿ ▸ ڊେͳΦϒδΣΫτ͸ϝϞϦͷ੍໿Λߟ͑Δ͜ͱ ▸ ΦϒδΣΫτͷޓ׵ੑʹؾΛ͚ͭΔ 51
  36. Practical IPC ·ͱΊ ▸ ProGuard ▸ IPC ʹؔΘΔ෦෼͸೉ಡԽΛճආ͢Δ ▸ ϓϩηεͷࢮ׆؂ࢹ

    ▸ ࢮΜͩϓϩηεʹ௨৴Λ͠ͳ͍ ▸ ௨৴૬खͷόϦσʔγϣϯ ▸ ୭ʹͰ΋ެ։͍͍ͯ͠ػೳ͔Ͳ͏͔Ͱ੍໿ΛܾΊΔ 52
  37. Practical IPC Reference ▸ Deep Dive into Android IPC/Binder Framework

    http://bit.ly/2dsFzaI ▸ Android Binder-IPC http://bit.ly/2gFKWcl ▸ Binder ͷ͸͡ΊͷҰาͱ Android ͷϓϩηεؒ௨৴ http://bit.ly/2fY9lWi ▸ Binder ͷ͸͡ΊͷҰา http://bit.ly/2fNs35k ▸ Open Binder http://bit.ly/2fNlP5h ▸ Intent ͷ֓ཁ http://bit.ly/2fANsvs 54