aidl 在 android 开发中的主要作用就是跨进程通讯来着,说到进程相比很多人都是非常熟悉了,但是为什么会有跨进程通讯这个概念呢?原来在 android 系统中,有这么一套安全机制,为了各个 Apk 数据的独立性、安全性,它们彼此之间是不能直接进行数据的访问的。所以为了实现多个 APK 之间的数据、方法、代码复用,我们通常采用的做法就是定义好 AIDL 接口,这样就能够既保护现有代码的逻辑性、同时又能够兼顾好封装性,各个团队之间只需要沟通好 AIDL 接口定义就可以了。
下面让我们直接进入主题吧,在进行 AIDL 定义的时候,通常会将公用的代码逻辑单独封装到一个独立的 APK 中,这个 APK 我们不妨成为服务器 Server。当定义好 Server 断逻辑之后,就可以供其他第三方代码调用了,这个第三方 Apk 我们不妨成为 Client。但是 Server 和 Client 方,必须同时保证 AIDL 文件名称相同,同时又在相同的包名下面。只有同时满足这两点的话,才能利用 AIDL 进行通讯。
假如有一套公用的计算方法,在多个第三方 APK 中都需要调用。所以定义两个 android project,一个服务端程序 AidlServer,一个客户端测试程序 TestClient。其中服务端、客户端的 AIDL 接口文件都位于包 "com.example.aidl 下面",定义好 ICal.aidl 文件,代码如下:
- package com.example.aidl;
- interface ICal {
- double doCal(double x, double y);
- }
在定义书写 aidl 文件代码的时候,语法规则跟 java 一致,切记不要忘记引入 package 或者少写了分号。当定义好 aidl 文件之后,并且没有错误的情况下,按住 ctrl+s 键保存编译,会发现项目的 gen 文件夹下面会自动生成一个同名的 java 文件。如果到这一步正确的生成了 java 文件的话,那么说明服务端,客户端的 AIDL 接口部分已经定义完成,那么接下来怎么将服务端的接口暴露给客户端调用呢?答案是通过 service,我们先来看一下 service 端的 CalService 代码:
- package com.example.service;
- import com.example.aidl.ICal;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.util.Log;
- public class CalService extends Service {
- private static final String TAG = CalService.class.getName();@Override public IBinder onBind(Intent intent) {
- return mBinder;
- }@Override public void onCreate() {
- Log.d(TAG, "onCreate action");
- super.onCreate();
- }@Override public void onStart(Intent intent, int startId) {
- Log.d(TAG, "onStart action");
- super.onStart(intent, startId);
- }@Override public void onDestroy() {
- Log.d(TAG, "onDestroy");
- super.onDestroy();
- }@Override public boolean onUnbind(Intent intent) {
- Log.d(TAG, "onUnbind");
- return super.onUnbind(intent);
- }
- private final ICal.Stub mBinder = new ICal.Stub() {
- @Override public double doCal(double x, double y) throws RemoteException {
- CalUtils calUtils = new CalUtils();
- double result = calUtils.add(x, y);
- return result;
- }
- };
- }
通过 CalService 可以很好的暴露 CalUtils 公用类里面的计算方法,CalUtils 代码如下:
- package com.example.service;
- public class CalUtils {
- public double add(double x, double y) {
- return x + y;
- }
- }
最后还需要在 AndroidManifest.xml 文件里面注册 CalService,代码如下:
- <service android:name="com.example.service.CalService">
- <intent-filter>
- <action android:name="com.example.service.CalService" />
- </intent-filter>
- </service>
到这里,服务器端的代码逻辑就完了,下面开始 Client 的测试代码编写。首先定义好一个计算 xml 页面,里面放置两个 EditText、一个 TextView、一个 Button、一个 TextView,这块的 xml 代码就不放出来了,稍后 demo 里面有。主要来看看后台的 Activity 代码,如下:
- package com.example.mytestpro;
- import com.example.aidl.ICal;
- import android.app.Activity;
- import android.content.ComponentName;
- import android.content.Context;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- import android.widget.TextView;
- public class CalActivity extends Activity implements OnClickListener {
- private static final String TAG = CalActivity.class.getName();
- private EditText etX,
- etY;
- private Button btnCal;
- private TextView tvInfo;
- private ICal mService;
- private ServiceConnection mServiceConnection = new ServiceConnection() {
- @Override public void onServiceDisconnected(ComponentName name) {
- Log.d(TAG, "do Disconnected action");
- mService = null;
- }
- @Override public void onServiceConnected(ComponentName name, IBinder service) {
- Log.d(TAG, "do Connected action");
- mService = ICal.Stub.asInterface(service);
- }
- };
- @Override protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_calctivity);
- initView();
- setClick();
- startBindServiceAction();
- }
- private void startBindServiceAction() {
- Bundle args = new Bundle();
- Intent intent = new Intent("com.example.service.CalService");
- intent.setPackage("com.example.aidlserver");
- intent.putExtras(args);
- bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
- }
- private void initView() {
- etX = (EditText) findViewById(R.id.etX);
- etY = (EditText) findViewById(R.id.etY);
- btnCal = (Button) findViewById(R.id.btnCal);
- tvInfo = (TextView) findViewById(R.id.tvInfo);
- }
- private void setClick() {
- btnCal.setOnClickListener(this);
- }@Override public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btnCal:
- excuteCalAction();
- break;
- default:
- break;
- }
- }
- private void excuteCalAction() {
- try {
- double x = Double.parseDouble(etX.getText().toString());
- double y = Double.parseDouble(etY.getText().toString());
- String result = "result:" + mService.doCal(x, y);
- tvInfo.setText(result);
- tvInfo.setTextColor(Color.RED);
- } catch(Exception e) {
- Log.d(TAG, e.getMessage());
- }
- }
- }
有兴趣的读者,可点击下载、。
来源: http://www.cnblogs.com/xiaocai20091687/p/xiacai_android_17.html