Android中AIDL通信机制分析
- 一、背景
·1、AIDL出现的原因
在android系统中,每一个程序都是运行在自己的进程中,进程之间无法进行通讯,为了在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作,实现IPC(进行间的通信)与J2e中的RMI类似。
·2、绑定service
我看了很多人都博客都没有说到这里,其实我个人感觉AIDL就是一个远程的客户端而已,把之前BindService的中service的继承类单独拿出来放到远程客户端,在本地绑定service中我们一般是在onBind方法中将内部定义好的一个继承Binder类的对象返回给activity,在active里面获得该对象然后去调用方法对于BindService的介绍见下一篇博客。但是这里不一样我们是要去另一个进程说白点也就是另一个应用里面去获得数据,因此我们需要一些接口上的规则,来规范进程间的通信,让服务端应用进行发送,客户端应用来接受。下面说一下规则是神马?
- 二、AIDL服务端的步骤
·1. 实现.aidl文件
以eclipse开发为例,我们需要在一般是在src文件夹下,新建一个包---文件夹,然后再该文件夹目录下新建一个文件该文件的后缀名以.aidl结尾,这是必须如此的。
·2. 在文件内部首先要给出包名,
·3. 在接口中用到的数据类型,除了基本类型,String,List,Map,CharSequence,之外其他的都需要导包,即使在同一个包内也是需要导包,因此里面的类,以及方法我们都是需要导包的。
·4. 安卓ADT一般会帮我们自动将写好的aidl文件编译生成一个java语法的接口类,这个借口在gen文件下,可以打开里面默认生成了一个内部抽象类stub该类继承Binder实现了起外部接口,
·5. 定义方法名称,所有的.aidl文件已经需要传递的对象接口需要在Service 与Client中各一份,最好是直接复制过去即可。
//----------------------------------下面是提供数据访问的服务端aidl文件定义:
package com.example.service;
interface DataService{
double getData(String arg);
}
·6. 下面就是在service的自定义类中来实现上面的aidl接口,上面已经解释了我们通过绑定service的来传递的其实是一个IBinder的对象,这里实际实现的接口是在 gen中自动生成的 DataService.java的抽象内部类 Stub,因为该类继承了Binder,而Binder则实现了IBinder接口,所以我们实际上需要的DataService.Stub的对象。
//---------------下面是服务端service中的代码,其实和绑定service的规则是一致的,
//===========目标是一致就是把一个IBinder的对象代理发到客户端,客户端接收到该对象,有了这个对象就可以调用该对象的一些方法。
import com.example.service.DataService; import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException; public class MyService extends Service { @Override
public IBinder onBind(Intent intent) {
// 这个binder就是要发送给远程客户端的对象,在建立连接后客户端得到该对象,调用该对象的方法来获取数据。
return binder;
}
// 还有一个需要注意的就是我们的service需要在配置文件里面进行注册,同时添加一个action的过滤器方便我们调用,绑定。
// 因为需要一个IBinder的对象返回而这个对象是一个接口,所以需要具体实现类的对象,Binder实现了该接口,因此我们需要创建一个Binder的对象,
// 又我们定义的aidl文件中的接口中被编译后会自动生成一个内部类stub,该内部类就继承了Binder
// 定义提供给客户端client调用的方法
Binder binder = new DataService.Stub() {
@Override
public double getData(String arg) throws RemoteException {
// TODO Auto-generated method stub if (arg.equals("a")) {
return 1;
} else if (arg.equals("b")) {
return 2;
} return 0;
}
}; }
//=====================上面直接运行跑起来就可以空的activity.
// 下面说下客户端的运行
// 客户端首先是要有aidl文件的上面已经说到了,下面就是直接上代码了
//---------------首先是布局文件,简单地两个按钮
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="92dp"
android:text="绑定service" /> <Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/button1"
android:layout_centerHorizontal="true"
android:layout_marginTop="88dp"
android:text="进程间的通信" /> </RelativeLayout>
下面是activity中的代码,我们要和服务端建立连接,就要在bindService方法中绑定到我们在服务端定义好的service类
Ok
import com.example.service.DataService; import android.os.Bundle;
import android.os.IBinder;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.View;
import android.widget.Button; public class MainActivity extends Activity { private Button button1, button2;
private DataService dataService; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2); // 绑定
button1.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent = new Intent(DataService.class.getName());
// 绑定service
/* bindService(service, conn, flags)该方法的参数解释一下
* 1.service: 表示通过该参数要启动的service
* 2.conn: 该参数是一个ServiceConnection,该对象是用于剑听雨service之间的连接情况,当访问者与service之间
* 成功连接时会调用onServiceConnected(ComponentName name, IBinder service)方法,通过该方法来获取
* service中的IBinder对象,通过对象来获取数据。连接失败onServiceDisconnected。
*/ bindService(intent, connection, Context.BIND_AUTO_CREATE);
}
}); button2.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
double result = dataService.getData("a");
System.out.println("--->>" + result); } catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
});
} // 客户端与服务进行连接
private ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub } @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
// 这些都是在API可以参考的,由SDK自动生成的DataService.Stub.asInterface的几个类
// 将客户端传递过来的IBinder对象,换为DataService对象,
// 在这里需要使用到aidl文件被编译后自动生成的内部类Stub中的一个方法asInterface,该方法的作用就是类型转换
dataService = DataService.Stub.asInterface(service);
}
};
}
总结其实这个aidl和绑定service并没有太大的区别,只不过我们把service的继承类放在了客户端,增加了一些协议规范罢了。
Android中AIDL通信机制分析的更多相关文章
- android中的通信机制总结
第一种:使用handler来进行通信 handler 大家可以把它想象成主线程(UI线程)的一个子线程,它可以给主线程(UI线程)发送数据从而更新主线程(UI线程)的UI与逻辑,handler ...
- Android中Alarm的机制
本次给大家分析的是Android中Alarm的机制所用源码为最新的Android4.4.4.首先简单介绍如何使用Alarm并给出其工作原理,接着分析Alarm和Timer以及Handler在完成定时任 ...
- Android中对消息机制(Handler)的再次解读
今天遇到一些关于在子线程中操作Handler的问题,感觉又要研究源代码了,但是关于Handler的话,我之前研究过,可以参考这篇文章:http://blog.csdn.net/jiangwei0910 ...
- 浅析Android中的消息机制(转)
原博客地址:http://blog.csdn.net/liuhe688/article/details/6407225 在分析Android消息机制之前,我们先来看一段代码: public class ...
- 浅析Android中的消息机制(转)
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制-解决:Only the original thread that created a view hierarchy can touch its views.
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 浅析Android中的消息机制
在分析Android消息机制之前,我们先来看一段代码: public class MainActivity extends Activity implements View.OnClickListen ...
- 重温Android中的消息机制
引入: 提到Android中的消息机制,大家应该都不陌生,我们在开发中不可避免的要和它打交道.从我们开发的角度来看,Handler是Android消息机制的上层接口.我们在平时的开发中只需要和Hand ...
- TensorFlow中的通信机制——Rendezvous(一)本地传输
背景 [作者:DeepLearningStack,阿里巴巴算法工程师,开源TensorFlow Contributor] 在TensorFlow源码中我们经常能看到一个奇怪的词——Rendezvous ...
随机推荐
- 行业集中度(Concentration Ratio)
行业集中度是决定市场结构最基本.最重要的因素,集中体现了市场的竞争和垄断程度,经常使用的集中度计量指标有:行业集中率(CRn指数).赫尔芬达尔—赫希曼指数(Herfindahl-HirschmanIn ...
- 用一段JS代码来比较各浏览器的极限内存与运算速度
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- hdu A Bug's Life
题目意思:给定一系列数对,例如a和b,表示a和b不是同一种性别,然后不断的给出这样的数对,问有没有性别不对的情况. 例如给定: 1 2 3 4 1 3 那这里就是说1和2不是同种性别 ...
- log4net 添加自定义日志到数据库
添加操作日志到数据库举例: (一)建立数据库的操作日志表,如下我建立了一个简单的日志表 (二)配置文件中的配置如下 <log4net> <!--错误日志记录数据库--> < ...
- c# select标签绑定枚举,并以Description做Text显示
今天在做项目时遇到一个问题: 开发中有些字段是枚举类型如 Dept 企业表中可能有个字段 Property 性质 0:事业单位,1:私企,2:外企,但有时我们不会单独为性质这个字段定义一张表, 而是在 ...
- JavaScript 几种简单的table切换
方法一:for循环+if判断当前点击与自定义数组是否匹配 <!DOCTYPE html> <html lang="en"> <head> < ...
- javascript中字符串的常用方法
<script type="text/javascript"> String substring(start,end): slice(start,end); 这两个函数 ...
- 生成一行html
//压缩 一行html Regex regReplaceBlank = new Regex(">(\\s+)<", RegexOptions.IgnoreCase); ...
- Java接入图灵机器人,实现与机器人聊天
很多人都玩过微信,其中就有与机器人聊天的功能:
- TestNG的一个不足之处
PS:本博客selenium分类不会记载selenium打开浏览器,定位元素,操作页面元素,切换到iframe,处理alter.confirm和prompt对话框这些在网上随处可见的信息:本博客此分类 ...