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