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());
}
}
}

有兴趣的读者,可点击下载服务端demo客户端demo

最新文章

  1. Ubuntu 树莓派2b交叉编译环境
  2. The method setPositiveButton(int, DialogInterface.OnClickListener) in the type AlertDialog.Builder is not applicable for the arguments
  3. unrecognized selector sent to instance
  4. Linux下VFP NEON浮点编译
  5. linux下mysql安装、目录结构、配置
  6. JS模态窗口返回值兼容问题解决方案
  7. angular 管理后台
  8. 【Markdown】Writing on Github - 在GitHub上写作
  9. UNICODE编码表
  10. uva 1335 - Beijing Guards(二分)
  11. IOS开发—UITableView重用机制的了解
  12. Jmeter 参数化请求实例
  13. thinter中lable标签控件(二)
  14. [开源]使用C# 对CPU卡基本操作封装
  15. 使用Filter过滤器+重写Request完美解决乱码问题
  16. count(*)、count(1)和count(列名)的区别
  17. 原生 JavaScript 实现 state 状态管理系统
  18. 【PAT】B1027 打印沙漏(20 分)
  19. python之udp协议的套接字
  20. uboot下emmc内容烧写(拷贝)步骤

热门文章

  1. POJ 1862 Stripies【哈夫曼/贪心/优先队列】
  2. Spring bean初始化以及管理
  3. [Git]Git 常用的操作命令
  4. Bluetooth篇 开发实例之八 匹配
  5. DATASNAP数据序列之FIREDAC的TFDJSONDataSets
  6. GoodSync
  7. CURL简单使用
  8. Tomcat Deployment failure ,locked one or more files
  9. ASP.NET MVC学习---(三)EF简单增删改查
  10. selenium执行报错:Process refused to die after 10 seconds, and couldn&#39;t taskkill it