Android开发——进程间通信之AIDL(二)
0. 前言
不论是Android还是其它操作系统。都会有自己的IPC机制。所谓IPC(Inter-Process Communication)即进程间通信。首先线程和进程是非常不同的概念,线程是CPU调用的最小单元,进程一般在PC和移动设备上指一个程序或者一个应用。一个进程能够包括多个线程。
IPC方式有非常多,在Android中经常使用的IPC方式包括Bundle、文件、Messenger、AIDL、ContentProvider和Socket等方式。
Android开发——进程间通信之AIDL(一)中介绍了AIDL的一个简单的使用方法,本篇主要解说使用AIDL传递自己定义对象的方式。
1. 序列化
aidl文件定义的接口支持的数据类型例如以下:
//1.Java的八种基本数据类型(byte。int,short。long,float,double,char。boolean)
//2.String
//3.CharSequence
//4.List。List中所有的元素必须是aidl文件支持的数据类型,比如List<String>
//5.Map。Map中所有的元素必须是aidl文件支持的数据类型,
//6.其它aidl定义的接口,要手动加入import
//7.其它aidl文件里申明的类。要手动加入import
在Android开发——进程间通信之AIDL(一)中的远程加法器中,我们传递的就是int型数据。这篇主要介绍最后一种,其它aidl文件里申明的类。这个类能够是自己定义的类。因此传递的数据类型组合更加自由。
可是自己定义的类要完毕IPC必须要序列化,序列化有Serializable和Parcelable两种方法,后者是Android中的序列化方式,因此效率更高,可是使用起来比較麻烦。
先看一下完整project的文件夹结构:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU0VVX0NhbHZpbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="" />
Person.java就是我们自己定义的类。
我们要实现的目的就是跨进程传递该对象的内容。首先实现该类的序列化。
package com.example.ipc_aidl_obj;
/**
* Java Bean
* Created by SEU_Calvin on 2017/3/25.
*/
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable{
private String name;
private int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
//从Parcel中读出之前写进的数据
protected Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
//反序列化,把我们通过writeToParcel方法写进的数据再读出来
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//实现 Parcelable 接口所需重写的方法1,一般不用管
@Override
public int describeContents() {
return 0;
}
//实现 Parcelable 接口所需重写的方法2,将对象的每一个字段写入到Parcel中
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
@Override
public String toString() {
return "Person{" +"name='" + name + '\'' +", age=" + age +'}';
}
}
我们的Person类实现了Parcelable接口,覆写了接口中describeContents()、writeToParcel() 的两个方法。前者返回当前对象的内容描写叙述,假设有描写叙述符则返回1,绝大多数情况要返回0。后者将对象写入序列化结构中。通过查看文档我们发现Parcel是没有writeShort()这种方法的。这也正是AIDL无法传递short类型的数据的原因。
然后就是静态创建构造器CREATOR。注意要加final修饰且名字必须为CREATOR不能更改,当中createFromParcel()用于把我们之前写进Parcel中的数据在读出来。这里要注意的是哪个字段先写进去,就先读取哪个字段。
这样我们自己定义的实体类就序列化好了。以备兴许使用。
2. 创建AIDL文件
共同拥有两个AIDL文件,一个是我们自己定义对象的声明,一个是接口声明。
在后者中须要将前者显式的import进来。
// IPersonn.aidl
package com.example.ipc_aidl_obj;
// Declare any non-default types here with import statements
parcelable Person; // IGetData.aidl
package com.example.ipc_aidl_obj;
// Declare any non-default types here with import statements
import com.example.ipc_aidl_obj.Person;
interface IGetData{
List<Person> getPersonList(in Person person);
}
接口中的getPersonList()方法将client传来的Person对象放入List中并返回List中所有的对象,这里须要说一下的就是getPersonList()方法中的inkeyword。即数据的走向,有in/out/inout三种类型。
依据需求选择合适的的数据走向类型。
3. 实现接口
package com.example.ipc_aidl_obj;
/**
* 服务端
* Created by SEU_Calvin on 2017/3/25.
*/
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.List; public class IRemoteService extends Service {
List<Person> persons;
@Nullable
@Override
public IBinder onBind(Intent intent) {
persons = new ArrayList<>();
return iBinder;
} private IBinder iBinder = new IGetData.Stub() { @Override
public List<Person> getPersonList(Person person) throws RemoteException {
persons.add(person);
return persons;
}
};
}
该服务端执行在独立进程,主要是对AIDL接口中的方法进行了实现。
4. client调用
首先进行服务的绑定。
并在ServiceConnection的回调方法中获得服务端返回的Binder实例。
Intent intent = newIntent(MainActivity.this,IRemoteService.class);
bindService(intent,serviceConnection,BIND_AUTO_CREATE); private ServiceConnection serviceConnection = newServiceConnection() {
@Override
public voidonServiceConnected(ComponentName name, IBinder service) {
mGetData =IGetData.Stub.asInterface(service);
}
@Override
public voidonServiceDisconnected(ComponentName name) {
}
};
当点击button后,就可以远程调用获得的IgetData对象的getPersonList()方法。将一个初始化好的Person类对象作为參数传入,将返回的List中的Person实例的内容所有Toast出来,这里点击了四次,加入了四个Person以及其年龄信息(亲爱的东大114岁了,Android6岁,我永远18岁QAQ)。效果例如以下。这样整个client和服务端的自己定义对象跨进程传递的过程就使用AIDL完毕了。
參考源代码地址点击下载。
请大家多点赞支持~
Android开发——进程间通信之AIDL(二)的更多相关文章
- 【Android开发VR实战】二.播放360°全景视频
转载请注明出处:http://blog.csdn.net/linglongxin24/article/details/53924006 本文出自[DylanAndroid的博客] [Android开发 ...
- Android开发——进程间通信之Bundle和文件
0. 前言 不论是Android还是其他操作系统,都会有自己的IPC机制,所谓IPC(Inter-Process Communication)即进程间通信.首先线程和进程是很不同的概念,线程是CPU ...
- Android开发-API指南-AIDL
Android Interface Definition Language (AIDL) 英文原文:http://developer.android.com/guide/components/aidl ...
- Android开发学习笔记(二)——编译和运行原理(1)
http://www.cnblogs.com/Pickuper/archive/2011/06/14/2078969.html 接着上一篇的内容,继续从全局了解Android.在清楚了Android的 ...
- android开发系列之aidl
aidl在android开发中的主要作用就是跨进程通讯来着,说到进程相比很多人都是非常熟悉了,但是为什么会有跨进程通讯这个概念呢?原来在android系统中,有这么一套安全机制,为了各个Apk数据的独 ...
- 【Android】进程间通信IPC——AIDL
AIDL官网定义AIDL(Android 接口定义语言)与您可能使用过的其他 IDL 类似. 您可以利用它定义客户端与服务使用进程间通信 (IPC) 进行相互通信时都认可的编程接口. 在 Androi ...
- Android开发 - 掌握ConstraintLayout(二)介绍
介绍 发布时间 ConstraintLayout是在2016的Google I/O大会上发布的,经过这么长时间的更新,现在已经非常稳定. 支持Android 2.3(API 9)+ 目前的Androi ...
- Android开发-浅谈架构(二)
写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应 ...
- Android开发基础规范(二)
转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/52614696 前言:Androi ...
随机推荐
- 大数据学习——spark安装
一主多从 1 上传压缩包 2 解压 -bin-hadoop2..tgz 删除安装包 -bin-hadoop2..tgz 重命名 mv spark-1.6.2-bin-hadoop2.6/ spark ...
- Python学习-day7 类 部分socket
这周还是继续关于类的学习,在面向对象的学习过程中又学习了网络编程,并且提交了编写FTP的作业. 复习一下类的相关概念和定义 类 属性 实例变量:内存中 ...
- Model View Controller(MVC) in PHP
The model view controller pattern is the most used pattern for today’s world web applications. It ha ...
- 什么是WSDL
WSDL定义 WSDL(Web Service Description Language) 指网络服务描述语言:是一种用来描述Web服务和说明Web服务通信的XML.WSDL用于描述WebServic ...
- iOS学习笔记31-从图册获取图片和视频
一.从图册中获取本地图片和视频 从图册中获取文件,我们使用的是UIImagePickerController,这个类我们在之前的摄像头中使用过,这里是链接:iOS学习笔记27-摄像头,这里我们使用的是 ...
- [luoguP1251] 餐巾计划问题(费用流)
传送门 模型 网络优化问题,用最小费用最大流解决. 实现 把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T. 1.从S向每个Xi连一条容量为ri,费用为0的有向边. 2.从每个Yi向T连一 ...
- BZOJ1068 [SCOI2007]压缩 【区间dp】
题目 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小 写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位 ...
- BZOJ2324 [ZJOI2011]营救皮卡丘 【费用流】
题目 皮卡丘被火箭队用邪恶的计谋抢走了!这三个坏家伙还给小智留下了赤果果的挑衅!为了皮卡丘,也为了正义,小智和他的朋友们义不容辞的踏上了营救皮卡丘的道路. 火箭队一共有N个据点,据点之间存在M条双向道 ...
- TCP面试题之为什么需要三次握手才能建立连接/四次挥手才能断开连接
为什么需要三次握手才能建立连接? 答:为了初始化Sequence Number(序列号)的初始值,要通知双方数据包的序号,作为以后通讯的序号,以保证在网络传输过程,不会因为网络原因而导致乱序: 为什么 ...
- java面试题之有哪几种方式可以让线程阻塞
线程阻塞方式: 1.join 2.sleep 3.yield 4.改变线程的优先级 5.将线程设置成守护线程(jvm中的垃圾回收线程) 参考:https://blog.csdn.net/liyucho ...