Slide 1

Slide 1 text

Practical IPC Keishin Yokomaku / shibuya.apk #11 @ GMO Yours

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Practical IPC 3

Slide 4

Slide 4 text

Practical IPC Inter-Process Communication (abbr. IPC) 4 Process A Process B

Slide 5

Slide 5 text

Practical IPC Inter-Process Communication (abbr. IPC) 5 App A App B

Slide 6

Slide 6 text

Practical IPC Inter-Process Communication (abbr. IPC) 6 App A System

Slide 7

Slide 7 text

Practical IPC Inter-Process Communication (abbr. IPC) 7 Client Server

Slide 8

Slide 8 text

Practical IPC IPC ͕࢖ΘΕ͍ͯΔ৔ॴ ▸ PackageManager ▸ e.g. PackageManager ͕ಈ͍͍ͯΔϓϩηεʹର͢Δ໰͍߹Θͤ ▸ Intent ▸ e.g. ϥϯνϟʔ͔ΒΞϓϦͷىಈ ▸ android.media.session, android.media.browser ▸ Android Auto ༻ͷΦʔσΟΦΞϓϦ޲͚ϑϨʔϜϫʔΫ 8

Slide 9

Slide 9 text

Practical IPC ࣗ෼Ͱ IPC ͯ͠ΈΔ ▸ ࡞Δ΋ͷ ▸ AIDL ▸ Service 9

Slide 10

Slide 10 text

Practical IPC AIDL ▸ Android Interface Definition Language ▸ Java ʹࣅͨจ๏Λ࣋ͬͨಛผͳݴޠ ▸ ΠϯλϑΣʔεΛఆٛ͢ΔͨΊʹ࢖͏ ▸ ࣮ࡍͷॲཧ͸ Java Ͱهड़͢Δ ▸ aidl ઐ༻ͷσΟϨΫτϦʹೖΕ͓ͯ͘ 10

Slide 11

Slide 11 text

Practical IPC AIDL ͷهड़ྫ package com.github.keithyokoma.aidl; interface SampleAidl { String getSomething(int value); } 11

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

Practical IPC ίϯύΠϧΤϥʔʹͳΔ AIDL ͷهड़ྫ 2 package com.github.keithyokoma.aidl; interface SampleAidl { String getSomething(int value); void doSomething(CustomObject object); } 13 ϓϦϛςΟϒܕɾStringܕɾҰ෦ͷίϨΫγϣϯܕҎ֎ͷܕ͸ಛผʹએݴ͠ͳ͍ݶΓ࢖͑ͳ͍

Slide 14

Slide 14 text

Practical IPC ಠࣗΫϥεΛ IPC Ͱ࢖͏ͨΊͷ parcelable Ωʔϫʔυ package com.github.keithyokoma.aidl; interface SampleAidl { String getSomething(int value); void doSomething(CustomObject object); } parcelable CustomObject; 14 CustomObject ͸ Parcelable Λ࣮૷γͨΫϥεͰ͋Δ͜ͱΛ໌ࣔ

Slide 15

Slide 15 text

Practical IPC ඇಉظॲཧͷͨΊͷ AIDL ͷه๏ package com.github.keithyokoma.aidl; oneway interface SampleAidl { String getSomething(int value); } 15 oneway Ωʔϫʔυ͕ͭ͘ͱɺϝιουݺͼग़͕͠ଈ࠲ʹฦ٫͞Ε݁Ռ͸ඇಉظʹฦͬͯ͘Δ

Slide 16

Slide 16 text

Practical IPC AIDL Λ࢖ͬͨ IPC ͷਤ 16 Client Server Proxy Stub IBinder

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

Practical IPC AIDL Λ࢖ͬͨ IPC ͷਤ 18 Client Server Proxy Stub IBinder ࣮ࡍʹ͸libbinder ΍ binder Ϟδϡʔϧ౳ͷॲཧ͕ؒʹ͋Δ

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

Practical IPC Service ͷ࣮૷2 22

Slide 23

Slide 23 text

Practical IPC Service ͷ࣮૷2 23

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

Practical IPC ͳͥ IPC Λ࢖͏ͷ͔ ▸ ଞͷΞϓϦͱόοΫάϥ΢ϯυͰ࿈ܞ͍ͨ͠ ▸ e.g. ଞͷΞϓϦʹ௚઀σʔλΛૹΓࠐΜͰԿΒ͔ͷॲཧΛͯ͠΋Β͍͍ͨ ▸ e.g. ଞͷΞϓϦʹσʔλͷऔಘΛ୅ཧͯ͠΋Β͍͍ͨ ▸ e.g. ଞͷΞϓϦ͕͍࣋ͬͯΔίϯςϯπΛૢ࡞͍ͨ͠ ▸ etc… 30

Slide 31

Slide 31 text

Practical IPC ͳͥ IPC Λ࢖͏ͷ͔ ▸ ྑ͍ͱ͜Ζ ▸ Activity ͷΈͳΒͣɺৗறܕ Service Ͱ΋࢖͑Δ ▸ όΠϯυҎ֎Ͱ Intent (broadcast ؚΉ) ͷ࢓૊ΈΛհ͞ͳ͍ͷͰಈ࡞΋͸΍͍ ▸ ਏ͍ͱ͜Ζ ▸ ؅ཧίετ͕͔͞Ή(֎෦ެ։લఏͳͷͰόʔδϣϯ؅ཧ͕ඞཁɾޙड़) ▸ ฼؋ΞϓϦ͕ແ͍ͱ໾ʹཱͨͳ͍ 31

Slide 32

Slide 32 text

Practical IPC IPC ͷ࢖͍ॴ ▸ SDK ͱͯ͠ΞϓϦͷಛఆͷػೳɾAPI Λެ։͢Δ ▸ e.g. ΦʔσΟΦͷ࠶ੜίϯτϩʔϧػೳΛ AIDL Ͱఆٛ͢Δ ▸ e.g. AIDL ܦ༝ͰΞϓϦʹΞυΦϯػೳΛ௥Ճ͢Δ ▸ etc… 32

Slide 33

Slide 33 text

Practical IPC IPC Λ࢖͏ͱ͖ͷ஫ҙ఺ ▸ IPC Ͱͷ௨৴૬खͷݕূ ▸ IPC Ͱ૝ఆ͞ΕΔྫ֎ ▸ AIDL ͷόʔδϣϯ؅ཧ ▸ ProGuard ͷઃఆ 33

Slide 34

Slide 34 text

Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ڐՄͨ͠௨৴૬खͱ͚ͩ IPC ͍ͨ͠ ▸ Կ΋͠ͳ͍ͱ୭ͱͰ΋ IPC Ͱ͖ͯ͠·͏ ▸ ηΩϡϦςΟϦεΫ ▸ ઀ଓ࣌ʹ୭͕௨৴ΛࢼΈ͍ͯΔ͔ݕূ͢Δ ▸ μϝͳ૬खͱͷίωΫγϣϯ͸མͱ͢ 34

Slide 35

Slide 35 text

Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ݕূʹ࢖͏৘ใ ▸ ύοέʔδ໊ ▸ ॺ໊ͷϋογϡ ▸ Android Auto ޲͚ API ͷ MediaBrowserService ͕ྑ͍ྫ ▸ xml ʹڐՄ͢Δύοέʔδ໊ͱॺ໊ͷϋογϡͷҰཡΛ͓࣋ͬͯ͘ ▸ http://bit.ly/2gdkUJP 35

Slide 36

Slide 36 text

Practical IPC ߟྀ͓ͯ͘͠΂͖ྫ֎ ▸ TransactionTooLargeException ▸ BadParcelableException ▸ DeadObjectException 36

Slide 37

Slide 37 text

Practical IPC TransactionTooLargeException 37

Slide 38

Slide 38 text

Practical IPC TransactionTooLargeException ▸ ϓϩηεؒ௨৴Ͱ࢖͑ΔϝϞϦۭؒͷ੍ݶΛ௒͑ͨ ▸ 1ϓϩηεʹׂΓ౰ͯΒΕΔϓϩηεؒ௨৴༻ͷϝϞϦۭؒ͸1mB ▸ ճආࡦ ▸ ಉ࣌ʹͨ͘͞Μϓϩηεؒ௨৴͠ͳ͍ ▸ Bitmap ͳͲڊେͳσʔλΛϓϩηεؒ௨৴ʹͷͤͳ͍ ▸ Ͳ͏ͯ͠΋ Bitmap Λ࢖͏ͱ͖͸ɺBitmap ͷαΠζΛࢦఆͰ͖ΔΑ͏ʹ͢Δ 38

Slide 39

Slide 39 text

Practical IPC Don’t interface RemoteService { void setBitmap(in Bitmap image); } 39 Do interface RemoteService { void setBitmap(in Uri imageUri); }

Slide 40

Slide 40 text

Practical IPC BadParcelableException 40

Slide 41

Slide 41 text

Practical IPC BadParcelableException 41 ▸ ޓ׵ੑͷͳ͍ Parcelable Λड͚औͬͨ ▸ Ϋϥεϩʔμͷҧ͍ΛߟྀʹೖΕΑ͏ ▸ ϑΟʔϧυͷ௥Ճɾ࡟আ͸৻ॏʹʢSerializableΑΓ͸΍͍͞͠ʣ ▸ ճආࡦ ▸ ΫϥεϩʔμΛஔ͖׵͑Δ

Slide 42

Slide 42 text

Practical IPC DeadObjectException 42

Slide 43

Slide 43 text

Practical IPC DeadObjectException ▸ ࢮΜͰ͍Δϓϩηεʹ௨৴ΛࢼΈͨ ▸ ࢮମऽΓɺμϝઈର ▸ ճආࡦ ▸ IBinder.DeathRecipient ΍ ServiceConnection Ͱࢮ׆؂ࢹ ▸ SDK ͱͯ͠ϥοϓͨ͠ΫϥεΛఏڙ͢Δ৔߹ɺࢮΜͩ͜ͱΛίʔϧόοΫ͢ΔΠ ϯλϑΣʔεΛผ్༻ҙ͢ΔͱΑ͍ 43

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

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

Slide 46

Slide 46 text

Practical IPC AIDL ͷόʔδϣϯ؅ཧ ▸ ϝιουΛΦʔόʔϩʔυ͍ͨ͠ ▸ ෆՄೳͳͷͰผ໊ʹ͢Δ͔͠ͳ͍ ▸ όουϊ΢ϋ΢Λ࢖͏(ޙड़) ▸ Parcelable Λมߋ͍ͨ͠ ▸ ϑΟʔϧυͷ௥Ճͷͱ͖ɺParcel ͔Βͷ෮ؼ΍ॻ͖ࠐΈͷॱ൪͸࠷ޙʹ௥Ճ 46

Slide 47

Slide 47 text

Practical IPC AIDL ͷόʔδϣϯ؅ཧʹ͓͚Δόουϊ΢ϋ΢ ▸ ΦʔόʔϩʔυͰ͖ͳ͍໰୊ ▸ ࣮͸ Service ͷ࣮૷ʹϝιου͕͋Γ͑͢͞Ε͹Φʔόʔϩʔυ͸Ͱ͖Δ ▸ e.g. ݺͼग़͠ઌͷ AIDL Ͱ hoge() ϝιουΛ hoge(int) ʹมߋɺͨͩ͠ Service ͷ࣮૷ʹ͸ hoge() ΋࢒ͯ͋͠Δ => ݺͼग़͠ݩͷΞϓϦͷ AIDL ʹ͸ hoge() ͔͠ͳͯ͘΋ hoge() ͸ͪΌΜͱݺ΂Δ 47

Slide 48

Slide 48 text

Practical IPC ProGuard ▸ ϝιου໊ͷ೉ಡԽ͸ඞͣճආ͢Δ ▸ ϝιου໊͕ղܾͰ͖ͳ͘ͳͬͯࢮΜͰ͠·͏ ▸ AIDL ΛؚΊͨ SDK ΍ϥΠϒϥϦΛ഑෍͢ΔͳΒɺProGuard ͷઃఆ΋ಉࠝ͢Δ 48

Slide 49

Slide 49 text

·ͱΊ 49

Slide 50

Slide 50 text

Practical IPC ·ͱΊ ▸ AIDL ͷ࢖͍ॴ ▸ ଞͷΞϓϦʹࣗ෼ͷΞϓϦͷ΋ͭػೳΛެ։͢Δ ▸ ΞυΦϯ௥Ճɺσʔλͷऔಘɾૹ৴ɺίϯςϯπͷૢ࡞ͳͲ ▸ SDK ͱͯ͠഑෍ ▸ Intent ͷΑ͏ͳதؒϨΠϠ͕ͳ͘ͳΔͷͰಈ࡞͸଎͍ ▸ ίʔϧόοΫ౳Λ༻ҙͯ͠։ൃऀϑϨϯυϦʔʹ͢Δ 50

Slide 51

Slide 51 text

Practical IPC ·ͱΊ ▸ AIDL ͷ੍໿ ▸ ΦʔόʔϩʔυෆՄ ▸ ϓϦϛςΟϒܕɺStringܕɺҰ෦ίϨΫγϣϯܕҎ֎͸ParcelableΛ࣮૷ ▸ Parcelable ͷ੍໿ ▸ ڊେͳΦϒδΣΫτ͸ϝϞϦͷ੍໿Λߟ͑Δ͜ͱ ▸ ΦϒδΣΫτͷޓ׵ੑʹؾΛ͚ͭΔ 51

Slide 52

Slide 52 text

Practical IPC ·ͱΊ ▸ ProGuard ▸ IPC ʹؔΘΔ෦෼͸೉ಡԽΛճආ͢Δ ▸ ϓϩηεͷࢮ׆؂ࢹ ▸ ࢮΜͩϓϩηεʹ௨৴Λ͠ͳ͍ ▸ ௨৴૬खͷόϦσʔγϣϯ ▸ ୭ʹͰ΋ެ։͍͍ͯ͠ػೳ͔Ͳ͏͔Ͱ੍໿ΛܾΊΔ 52

Slide 53

Slide 53 text

Practical IPC Keishin Yokomaku / shibuya.apk #11 @ GMO Yours

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

DroidKaigi Registration has started! http://bit.ly/2gFFK8z 55