什么是AIDL
Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。
与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。
Android的四大组件中的三个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。
实现AIDL
建立AIDLServer和AIDLClient项目,如下图:
① AIDLServer
新建一个ICalculate接口,并将文件后缀修改为.aidl
1 package com.example.calculate;
2
3 interface ICalculate {
4 double doCalculate(double a, double b);
5 }
.aidl编译后会在“gen/包名/”目录中生成ICalculate.java的接口文件
新建一个CalculateService服务,该服务中的MyBinder 实现了ICalculate接口
1 public class CalculateService extends Service {
2
3 private MyBinder mBinder;
4
5 @Override
6 public void onCreate() {
7 // TODO Auto-generated method stub
8 super.onCreate();
9
10 mBinder = new MyBinder();
11
12 }
13
14
15 @Override
16 public void onDestroy() {
17 // TODO Auto-generated method stub
18 super.onDestroy();
19 }
20
21
22 @Override
23 public IBinder onBind(Intent arg0) {
24 // TODO Auto-generated method stub
25 return mBinder;
26 }
27
28
29 public class MyBinder extends ICalculate.Stub
30 {
31
32 @Override
33 public double doCalculate(double a, double b) throws RemoteException {
34 // TODO Auto-generated method stub
35 return a+b;
36 }
37
38 }
39
40 }
AndroidManifest.xml中声明Service
1 <service
2 android:name="com.example.aidlserver.CalculateService"
3 android:enabled="true" >
4 <intent-filter>
5 <action android:name="com.example.calculate.ICalculate" />
6 </intent-filter>
7 </service>
② AIDLClient
将AIDLServer中的com.example.calculate包拷入AIDLClient(跨进程调用必须包相同)
使用bindService方法来调用CalculateService服务
1 ICalculate mBinder;
2
3 ServiceConnection mCon=new ServiceConnection() {
4
5 @Override
6 public void onServiceDisconnected(ComponentName arg0) {
7 // TODO Auto-generated method stub
8
9 }
10
11 @Override
12 public void onServiceConnected(ComponentName arg0, IBinder arg1) {
13 mBinder=ICalculate.Stub.asInterface(arg1);
14
15
16
17 }
18 };
1 Intent intent=new Intent("com.example.calculate.ICalculate");
bindService(intent, mCon, Context.BIND_AUTO_CREATE);
MainActivity.java代码如下:
1 public class MainActivity extends ActionBarActivity {
2
3
4 Button btnPlus;
5 EditText et1;
6 EditText et2;
7 TextView tvResult;
8
9
10 ICalculate mBinder;
11
12 ServiceConnection mCon=new ServiceConnection() {
13
14 @Override
15 public void onServiceDisconnected(ComponentName arg0) {
16 // TODO Auto-generated method stub
17
18 }
19
20 @Override
21 public void onServiceConnected(ComponentName arg0, IBinder arg1) {
22 mBinder=ICalculate.Stub.asInterface(arg1);
23
24
25
26 }
27 };
28
29
30 @Override
31 protected void onCreate(Bundle savedInstanceState) {
32 super.onCreate(savedInstanceState);
33 setContentView(R.layout.activity_main);
34
35
36 btnPlus=(Button) findViewById(R.id.btnPlus);
37 et1=(EditText) findViewById(R.id.et1);
38 et2=(EditText) findViewById(R.id.et2);
39 tvResult=(TextView) findViewById(R.id.tvResult);
40
41 btnPlus.setOnClickListener(new OnClickListener() {
42
43 @Override
44 public void onClick(View arg0) {
45
46 if(mBinder==null)
47 {
48 return;
49 }
50
51 String num1=et1.getText().toString();
52 String num2=et2.getText().toString();
53
54 if(TextUtils.isEmpty(num1)||TextUtils.isEmpty(num2))
55 {
56 return;
57 }
58
59 double d1=Double.parseDouble(num1);
60 double d2=Double.parseDouble(num2);
61
62 double total=-1;
63
64 Log.i("MainActivity", "onClick() d1="+d1+" d2"+d2);
65
66
67 try {
68 total=mBinder.doCalculate(d1, d2);
69 } catch (RemoteException e) {
70 // TODO Auto-generated catch block
71 e.printStackTrace();
72 }
73
74
75 tvResult.setText("结果:"+total);
76
77
78 }
79 });
80
81 Intent intent=new Intent("com.example.calculate.ICalculate");
82
83 bindService(intent, mCon, Context.BIND_AUTO_CREATE);
84
85 }
86
87
88
89 @Override
90 protected void onDestroy() {
91 // TODO Auto-generated method stub
92 super.onDestroy();
93 unbindService(mCon);
94 }
95
96
97
98
99 }
注:bindService后记得unbindService