Android中的跨进程调用技术AIDL

什么是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

原文地址:https://www.cnblogs.com/l2rf/p/4959629.html