Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
Practical IPC
Keishin Yokomaku
November 22, 2016
Technology
0
150
Practical IPC
Keishin Yokomaku
November 22, 2016
Tweet
Share
More Decks by Keishin Yokomaku
See All by Keishin Yokomaku
持続的なアプリ開発のためのDXを支える技術
keithyokoma
2
3.8k
Make the objects serializable with kotlinx.serialization
keithyokoma
0
2.5k
Kotlin で書く Gradle Custom Tasks
keithyokoma
0
350
DX Improvements
keithyokoma
3
300
Get Things Done with Gradle Custom Tasks
keithyokoma
1
81
詳解 Android Auto - 使い方からそれを支える技術まで -
keithyokoma
1
1.8k
Fail fast, Fail cheap, Fail automatically: Localization
keithyokoma
0
120
WebView😇😇😇
keithyokoma
0
560
Android 1.5 - 8.0 Walk through - Retro/Prospective Android Application Development
keithyokoma
4
240
Other Decks in Technology
See All in Technology
ZephyrRTOSのLongan Nanoへの移植
tokitahiroshi
0
110
DOM Invader - prototype pollution対応の衝撃 - / DOM Invader - prototype pollution
okuken
0
170
【toranoana.deno#7】Denoからwasmを呼び出す基礎
toranoana
0
140
【SAP知らない人向け】SAP on AWS 個人学習メモ/sap-on-aws-study
emiki
3
2.4k
UIKitのアップデート #WWDC22
akatsuki174
4
360
紙にまつわる苦しみを機能化してきた カミナシの歴史
kaminashi
0
1.4k
FoodTechにおける商流・金流・物流の進化/Evolution of Commercial, Financial, and Logistics in FoodTech
dskst
0
420
【Pythonデータ分析勉強会#33】「DearPyGuiに入門しました」の続き~Image-Processing-Node-Editor~
kazuhitotakahashi
0
190
Laravel.shibuyaで改善してきた IRT勉強会の運営方法について / IRT Study Session Improved Through Laravel Shibuya
fendo181
0
130
スクラムのスケールとチームトポロジー / Scaled Scrum and Team Topologies
daiksy
1
460
Introduction to MLOps
asei
8
1.4k
要約 "Add Live Text interaction to your app"
ushisantoasobu
0
150
Featured
See All Featured
The Language of Interfaces
destraynor
148
20k
Statistics for Hackers
jakevdp
781
210k
Stop Working from a Prison Cell
hatefulcrawdad
261
17k
No one is an island. Learnings from fostering a developers community.
thoeni
9
1.3k
Build your cross-platform service in a week with App Engine
jlugia
219
17k
Code Review Best Practice
trishagee
43
9.3k
Building Your Own Lightsaber
phodgson
94
4.6k
It's Worth the Effort
3n
172
25k
Rebuilding a faster, lazier Slack
samanthasiow
62
7.2k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
237
19k
Bootstrapping a Software Product
garrettdimon
296
110k
Infographics Made Easy
chrislema
233
17k
Transcript
Practical IPC Keishin Yokomaku / shibuya.apk #11 @ GMO Yours
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
Practical IPC 3
Practical IPC Inter-Process Communication (abbr. IPC) 4 Process A Process
B
Practical IPC Inter-Process Communication (abbr. IPC) 5 App A App
B
Practical IPC Inter-Process Communication (abbr. IPC) 6 App A System
Practical IPC Inter-Process Communication (abbr. IPC) 7 Client Server
Practical IPC IPC ͕ΘΕ͍ͯΔॴ ▸ PackageManager ▸ e.g. PackageManager ͕ಈ͍͍ͯΔϓϩηεʹର͢Δ͍߹Θͤ
▸ Intent ▸ e.g. ϥϯνϟʔ͔ΒΞϓϦͷىಈ ▸ android.media.session, android.media.browser ▸ Android Auto ༻ͷΦʔσΟΦΞϓϦ͚ϑϨʔϜϫʔΫ 8
Practical IPC ࣗͰ IPC ͯ͠ΈΔ ▸ ࡞Δͷ ▸ AIDL ▸
Service 9
Practical IPC AIDL ▸ Android Interface Definition Language ▸ Java
ʹࣅͨจ๏Λ࣋ͬͨಛผͳݴޠ ▸ ΠϯλϑΣʔεΛఆٛ͢ΔͨΊʹ͏ ▸ ࣮ࡍͷॲཧ Java Ͱهड़͢Δ ▸ aidl ઐ༻ͷσΟϨΫτϦʹೖΕ͓ͯ͘ 10
Practical IPC AIDL ͷهड़ྫ package com.github.keithyokoma.aidl; interface SampleAidl { String
getSomething(int value); } 11
Practical IPC ίϯύΠϧΤϥʔʹͳΔ AIDL ͷهड़ྫ 1 package com.github.keithyokoma.aidl; interface SampleAidl
{ String getSomething(int value); String getSomething(int value, boolean flag); } 12 ΦʔόʔϩʔυͰ͖ͳ͍
Practical IPC ίϯύΠϧΤϥʔʹͳΔ AIDL ͷهड़ྫ 2 package com.github.keithyokoma.aidl; interface SampleAidl
{ String getSomething(int value); void doSomething(CustomObject object); } 13 ϓϦϛςΟϒܕɾStringܕɾҰ෦ͷίϨΫγϣϯܕҎ֎ͷܕಛผʹએݴ͠ͳ͍ݶΓ͑ͳ͍
Practical IPC ಠࣗΫϥεΛ IPC Ͱ͏ͨΊͷ parcelable Ωʔϫʔυ package com.github.keithyokoma.aidl; interface
SampleAidl { String getSomething(int value); void doSomething(CustomObject object); } parcelable CustomObject; 14 CustomObject Parcelable Λ࣮γͨΫϥεͰ͋Δ͜ͱΛ໌ࣔ
Practical IPC ඇಉظॲཧͷͨΊͷ AIDL ͷه๏ package com.github.keithyokoma.aidl; oneway interface SampleAidl
{ String getSomething(int value); } 15 oneway Ωʔϫʔυ͕ͭ͘ͱɺϝιουݺͼग़͕͠ଈ࠲ʹฦ٫͞Ε݁Ռඇಉظʹฦͬͯ͘Δ
Practical IPC AIDL Λͬͨ IPC ͷਤ 16 Client Server Proxy
Stub IBinder
Practical IPC AIDL Λͬͨ IPC ͷਤ 17 Client Server Proxy
Stub IBinder AIDL Λॻ͍ͯϏϧυ͢Δͱࣗಈੜ͞ΕΔ
Practical IPC AIDL Λͬͨ IPC ͷਤ 18 Client Server Proxy
Stub IBinder ࣮ࡍʹlibbinder binder Ϟδϡʔϧͷॲཧ͕ؒʹ͋Δ
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
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
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
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
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
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
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
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
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
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
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
Practical IPC ͳͥ IPC Λ͏ͷ͔ ▸ ଞͷΞϓϦͱόοΫάϥϯυͰ࿈ܞ͍ͨ͠ ▸ e.g. ଞͷΞϓϦʹσʔλΛૹΓࠐΜͰԿΒ͔ͷॲཧΛͯ͠Β͍͍ͨ
▸ e.g. ଞͷΞϓϦʹσʔλͷऔಘΛཧͯ͠Β͍͍ͨ ▸ e.g. ଞͷΞϓϦ͕͍࣋ͬͯΔίϯςϯπΛૢ࡞͍ͨ͠ ▸ etc… 30
Practical IPC ͳͥ IPC Λ͏ͷ͔ ▸ ྑ͍ͱ͜Ζ ▸ Activity ͷΈͳΒͣɺৗறܕ
Service Ͱ͑Δ ▸ όΠϯυҎ֎Ͱ Intent (broadcast ؚΉ) ͷΈΛհ͞ͳ͍ͷͰಈ࡞͍ ▸ ਏ͍ͱ͜Ζ ▸ ཧίετ͕͔͞Ή(֎෦ެ։લఏͳͷͰόʔδϣϯཧ͕ඞཁɾޙड़) ▸ ؋ΞϓϦ͕ແ͍ͱʹཱͨͳ͍ 31
Practical IPC IPC ͷ͍ॴ ▸ SDK ͱͯ͠ΞϓϦͷಛఆͷػೳɾAPI Λެ։͢Δ ▸ e.g.
ΦʔσΟΦͷ࠶ੜίϯτϩʔϧػೳΛ AIDL Ͱఆٛ͢Δ ▸ e.g. AIDL ܦ༝ͰΞϓϦʹΞυΦϯػೳΛՃ͢Δ ▸ etc… 32
Practical IPC IPC Λ͏ͱ͖ͷҙ ▸ IPC Ͱͷ௨৴૬खͷݕূ ▸ IPC Ͱఆ͞ΕΔྫ֎
▸ AIDL ͷόʔδϣϯཧ ▸ ProGuard ͷઃఆ 33
Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ڐՄͨ͠௨৴૬खͱ͚ͩ IPC ͍ͨ͠ ▸ Կ͠ͳ͍ͱ୭ͱͰ
IPC Ͱ͖ͯ͠·͏ ▸ ηΩϡϦςΟϦεΫ ▸ ଓ࣌ʹ୭͕௨৴ΛࢼΈ͍ͯΔ͔ݕূ͢Δ ▸ μϝͳ૬खͱͷίωΫγϣϯམͱ͢ 34
Practical IPC IPC Ͱͷ௨৴૬खͷόϦσʔγϣϯ ▸ ݕূʹ͏ใ ▸ ύοέʔδ໊ ▸ ॺ໊ͷϋογϡ
▸ Android Auto ͚ API ͷ MediaBrowserService ͕ྑ͍ྫ ▸ xml ʹڐՄ͢Δύοέʔδ໊ͱॺ໊ͷϋογϡͷҰཡΛ͓࣋ͬͯ͘ ▸ http://bit.ly/2gdkUJP 35
Practical IPC ߟྀ͓͖ͯ͘͠ྫ֎ ▸ TransactionTooLargeException ▸ BadParcelableException ▸ DeadObjectException 36
Practical IPC TransactionTooLargeException 37
Practical IPC TransactionTooLargeException ▸ ϓϩηεؒ௨৴Ͱ͑ΔϝϞϦۭؒͷ੍ݶΛ͑ͨ ▸ 1ϓϩηεʹׂΓͯΒΕΔϓϩηεؒ௨৴༻ͷϝϞϦۭؒ1mB ▸ ճආࡦ ▸
ಉ࣌ʹͨ͘͞Μϓϩηεؒ௨৴͠ͳ͍ ▸ Bitmap ͳͲڊେͳσʔλΛϓϩηεؒ௨৴ʹͷͤͳ͍ ▸ Ͳ͏ͯ͠ Bitmap Λ͏ͱ͖ɺBitmap ͷαΠζΛࢦఆͰ͖ΔΑ͏ʹ͢Δ 38
Practical IPC Don’t interface RemoteService { void setBitmap(in Bitmap image);
} 39 Do interface RemoteService { void setBitmap(in Uri imageUri); }
Practical IPC BadParcelableException 40
Practical IPC BadParcelableException 41 ▸ ޓੑͷͳ͍ Parcelable Λड͚औͬͨ ▸ Ϋϥεϩʔμͷҧ͍ΛߟྀʹೖΕΑ͏
▸ ϑΟʔϧυͷՃɾআ৻ॏʹʢSerializableΑΓ͍͞͠ʣ ▸ ճආࡦ ▸ ΫϥεϩʔμΛஔ͖͑Δ
Practical IPC DeadObjectException 42
Practical IPC DeadObjectException ▸ ࢮΜͰ͍Δϓϩηεʹ௨৴ΛࢼΈͨ ▸ ࢮମऽΓɺμϝઈର ▸ ճආࡦ ▸
IBinder.DeathRecipient ServiceConnection Ͱࢮ׆ࢹ ▸ SDK ͱͯ͠ϥοϓͨ͠ΫϥεΛఏڙ͢Δ߹ɺࢮΜͩ͜ͱΛίʔϧόοΫ͢ΔΠ ϯλϑΣʔεΛผ్༻ҙ͢ΔͱΑ͍ 43
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
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
Practical IPC AIDL ͷόʔδϣϯཧ ▸ ϝιουΛΦʔόʔϩʔυ͍ͨ͠ ▸ ෆՄೳͳͷͰผ໊ʹ͢Δ͔͠ͳ͍ ▸ όουϊϋΛ͏(ޙड़)
▸ Parcelable Λมߋ͍ͨ͠ ▸ ϑΟʔϧυͷՃͷͱ͖ɺParcel ͔Βͷ෮ؼॻ͖ࠐΈͷॱ൪࠷ޙʹՃ 46
Practical IPC AIDL ͷόʔδϣϯཧʹ͓͚Δόουϊϋ ▸ ΦʔόʔϩʔυͰ͖ͳ͍ ▸ ࣮ Service ͷ࣮ʹϝιου͕͋Γ͑͢͞ΕΦʔόʔϩʔυͰ͖Δ
▸ e.g. ݺͼग़͠ઌͷ AIDL Ͱ hoge() ϝιουΛ hoge(int) ʹมߋɺͨͩ͠ Service ͷ࣮ʹ hoge() ͯ͋͠Δ => ݺͼग़͠ݩͷΞϓϦͷ AIDL ʹ hoge() ͔͠ͳͯ͘ hoge() ͪΌΜͱݺΔ 47
Practical IPC ProGuard ▸ ϝιου໊ͷಡԽඞͣճආ͢Δ ▸ ϝιου໊͕ղܾͰ͖ͳ͘ͳͬͯࢮΜͰ͠·͏ ▸ AIDL ΛؚΊͨ
SDK ϥΠϒϥϦΛ͢ΔͳΒɺProGuard ͷઃఆಉࠝ͢Δ 48
·ͱΊ 49
Practical IPC ·ͱΊ ▸ AIDL ͷ͍ॴ ▸ ଞͷΞϓϦʹࣗͷΞϓϦͷͭػೳΛެ։͢Δ ▸ ΞυΦϯՃɺσʔλͷऔಘɾૹ৴ɺίϯςϯπͷૢ࡞ͳͲ
▸ SDK ͱͯ͠ ▸ Intent ͷΑ͏ͳதؒϨΠϠ͕ͳ͘ͳΔͷͰಈ࡞͍ ▸ ίʔϧόοΫΛ༻ҙͯ͠։ൃऀϑϨϯυϦʔʹ͢Δ 50
Practical IPC ·ͱΊ ▸ AIDL ͷ੍ ▸ ΦʔόʔϩʔυෆՄ ▸ ϓϦϛςΟϒܕɺStringܕɺҰ෦ίϨΫγϣϯܕҎ֎ParcelableΛ࣮
▸ Parcelable ͷ੍ ▸ ڊେͳΦϒδΣΫτϝϞϦͷ੍Λߟ͑Δ͜ͱ ▸ ΦϒδΣΫτͷޓੑʹؾΛ͚ͭΔ 51
Practical IPC ·ͱΊ ▸ ProGuard ▸ IPC ʹؔΘΔ෦ಡԽΛճආ͢Δ ▸ ϓϩηεͷࢮ׆ࢹ
▸ ࢮΜͩϓϩηεʹ௨৴Λ͠ͳ͍ ▸ ௨৴૬खͷόϦσʔγϣϯ ▸ ୭ʹͰެ։͍͍ͯ͠ػೳ͔Ͳ͏͔Ͱ੍ΛܾΊΔ 52
Practical IPC Keishin Yokomaku / shibuya.apk #11 @ GMO Yours
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
DroidKaigi Registration has started! http://bit.ly/2gFFK8z 55