1、爲什麼要有AIDL?
無論學什麼東西,最先得弄明白爲什麼要有這個東西,不要說存在即是合理,存在肯定合理,但是你還是沒有明白。對於AIDL有一些人的淺顯概念就是,AIDL可以跨進程訪問其他應用程序,和其他應用程序通訊,那我告訴你,很多技術都可以訪問,如廣播(應用A在AndroidManifest.xml中註冊指定Action的廣播)應用B發送指定Action的廣播,A就能收到信息,這樣也能看成不同應用之間完成了通訊(但是這種通訊是單向的);還如ContentProvider,通過URI接口暴露數據給其他應用訪問;但是這種都算不上是應用之間的通訊。可能最讓人迷惑的是Android推出來了Messager,它就是完成應用之間的通訊的。那麼爲什麼還要有AIDL呢,官方文檔介紹AIDL中有這麼一句話:
1
|
Note: Using AIDL is necessary only
if you allow clients from different applications to access your service
for IPC and want to handle multithreading in your service. If you
do not need to perform concurrent IPC across different applications, you should create your
interface by implementing a Binder or,
if you want to perform IPC, but
do not need to handle multithreading, implement your
interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL. |
2、AIDL使用
第一、定義AIDL文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// IRemoteService.aidl package
com.example.android; // Declare any non-default types here with import statements /** Example service interface */ interface
IRemoteService { /** Request the process ID of this service, to do evil things with it. */ int
getPid(); /** Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void
basicTypes( int
anInt, long aLong,
boolean aBoolean,
float aFloat, double
aDouble, String aString); } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
package
com.example.service; import
com.example.android.IRemoteService; import
android.app.Service; import
android.content.Intent; import
android.os.IBinder; import
android.os.Process; public
class DDService extends
Service { @Override public
void onCreate() { super .onCreate(); System.out.println( "DDService onCreate........"
+ "Thread: "
+ Thread.currentThread().getName()); } @Override public
IBinder onBind(Intent arg0) { System.out.println( "DDService onBind" ); return
mBinder; } private
final IRemoteService.Stub mBinder =
new IRemoteService.Stub() { public
int getPid(){ System.out.println( "Thread: "
+ Thread.currentThread().getName()); System.out.println( "DDService getPid " ); return
Process.myPid(); } public
void basicTypes( int
anInt, long
aLong, boolean
aBoolean, float
aFloat, double
aDouble, String aString) { System.out.println( "Thread: "
+ Thread.currentThread().getName()); System.out.println( "basicTypes aDouble: "
+ aDouble + " anInt: "
+ anInt+ " aBoolean "
+ aBoolean+ " aString "
+ aString); } }; } |
這樣我們的服務端就完成了,把服務端運行到模擬器(或者手機上),等一會可以看一下打印信息,重點看“線程名”
第三、實現客戶端測試代碼新建另一個工程,同樣需要添加AIDL協議文件(這是一個標準的協議文件,定義對外服務),這裏我列出來我的測試代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
package
com.example.aidlclient; import
android.app.Activity; import
android.content.ComponentName; import
android.content.Context; import
android.content.Intent; import
android.content.ServiceConnection; import
android.os.Bundle; import
android.os.IBinder; import
android.os.Process; import
android.os.RemoteException; import
android.view.View; import
com.example.android.IRemoteService; public
class MainActivity extends
Activity { private
IRemoteService remoteService; @Override public
void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); } ServiceConnection conn =
new ServiceConnection() { @Override public
void onServiceDisconnected(ComponentName name) { } @Override public
void onServiceConnected(ComponentName name, IBinder service) { remoteService = IRemoteService.Stub.asInterface(service); try
{ int
pid = remoteService.getPid(); int
currentPid = Process.myPid(); System.out.println( "currentPID: "
+ currentPid + " remotePID: "
+ pid); remoteService.basicTypes( 12 ,
1223 , true ,
12 .2f, 12.3 ,
"我們的愛,我明白" ); }
catch (RemoteException e) { e.printStackTrace(); } System.out.println( "bind success! "
+ remoteService.toString()); } }; /** * 監聽按鈕點擊 * @param view */ public
void buttonClick(View view) { System.out.println( "begin bindService" ); Intent intent =
new Intent( "duanqing.test.aidl" ); bindService(intent, conn, Context.BIND_AUTO_CREATE); } @Override protected
void onDestroy() { super .onDestroy(); unbindService(conn); } } |
4、執行點擊客戶端按鈕,執行,看打印信息:
看服務端打印,DDService onCreate..........Thread: main,主線程,當客戶端調用服務端getPid方法時,服務端是在Thread: Binder2中執行,當客戶端調用服務端basicType方法時,服務端是在Thread:Binder1中執行