AIDL
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);
}
}
|
看服务端打印,DDService onCreate..........Thread: main,主线程,当客户端调用服务端getPid方法时,服务端是在Thread: Binder2中执行,当客户端调用服务端basicType方法时,服务端是在Thread:Binder1中执行