Lock in $30 Savings on PRO—Offer Ends Soon! ⏳

Practical IPC

Practical IPC

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