Android IPC机制(三)使用AIDL实现跨进程方法调用
上一篇文章中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messenger是以串行的方式来处理客户端发来的信息,如果有大量的消息发到服务端,服务端仍然一个一个的处理再响应客户端显然是不合适的。另外,Messenger用来进程间进行数据传递但是却不能满足跨进程的方法调用,接下来我们来使用AIDL来实现跨进程方法调用
1. 创建AIDL文件
我们将项目的目录结构调为Android模式,在java同级目录创建aidl文件夹,在文件夹中创建一个包名和应用包名一致的包
我们先创建一个IGameManager.aidl的文件,这里面有两个方法分别是addGame和getGameList。(IGameManager.aidl)
package com.example.liuwangshu.moonaidl;
import com.example.liuwangshu.moonaidl.Game;
interface IGameManager {
List<Game>getGameList();
void addGame(in Game game);
}
在AIDL文件中支持的数据类型包括:
- 基本数据类型
- String和CharSequence
- List:只支持ArrayList,里面的元素都必须被AIDL支持
- Map:只支持HashMap,里面的元素必须被AIDL 支持
- 实现Parcelable接口的对象
- 所有AIDL接口
在IGameManager.aidl中我们用到了Game这个类,这个类实现了Parcelable,在AIDL 文件中我们要import 进来,来看看Game类。(Game.java)
package com.example.liuwangshu.moonaidl;
import android.os.Parcel;
import android.os.Parcelable;
public class Game implements Parcelable {
public String gameName;
public String gameDescribe;
public Game(String gameName,String gameDescribe){
this.gameName=gameName;
this.gameDescribe=gameDescribe;
} protected Game(Parcel in) {
gameName=in.readString();
gameDescribe=in.readString();
} public static final Creator<Game> CREATOR = new Creator<Game>() {
@Override
public Game createFromParcel(Parcel in) {
return new Game(in);
} @Override
public Game[] newArray(int size) {
return new Game[size];
}
}; @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(gameName);
dest.writeString(gameDescribe);
}
}
在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)
package com.example.liuwangshu.moonaidl;
parcelable Game;
这个时候我们重新编译程序,工程就会自动生成IGameManager.aidl对应的接口文件,这个文件生成的位置和Eclipse的位置不同,我们将项目的目录结构调整为project模式,在app–>build–>generated–>soure–>aidl–>debug目录下我们找到自己的包名文件,在文件中有一个接口文件IGameManager。
IGameManager接口文件的代码这里就不说了,有兴趣的可以下载本项目的源码去了解下。
2. 创建服务端
服务端我们在onCreate方法中创建了两个游戏的信息并创建Binder对象实现了AIDL的接口文件中的方法,并在onBind方法中将Binder对象返回。(AIDLService.java)
package com.example.liuwangshu.moonaidl;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class AIDLService extends Service{
private CopyOnWriteArrayList<Game> mGameList=new CopyOnWriteArrayList<Game>();
private Binder mBinder= new IGameManager.Stub() {
@Override
public List<Game> getGameList() throws RemoteException {
return mGameList;
} @Override
public void addGame(Game game) throws RemoteException {
mGameList.add(game);
}
}; @Override
public void onCreate() {
super.onCreate();
mGameList.add(new Game("九阴真经ol", "最好玩的武侠网游"));
mGameList.add(new Game("大航海时代ol","最好玩的航海网游")); }
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
}
当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:
<service android:name=".AIDLService" android:process=":remote"></service>
3. 客户端调用
最后我们在客户端onCreate方法中调用bindService方法绑定远程服务端,绑定成功后将返回的Binder对象转换为AIDL接口,这样我们就可以通过这个接口来调用远程服务端的方法了。(AIDLActivity.java)
package com.example.liuwangshu.moonaidl;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import java.util.List;
public class AIDLActivity extends AppCompatActivity {
private final static String TAG="AIDLActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aidl);
Intent mIntent=new Intent(AIDLActivity.this,AIDLService.class);
bindService(mIntent,mServiceConnection, Context.BIND_AUTO_CREATE);
} private ServiceConnection mServiceConnection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
IGameManager iGameManager=IGameManager.Stub.asInterface(service);
Game game=new Game("月影传说","最好玩的武侠单机游戏");
try {
iGameManager.addGame(game);
List<Game> mList=iGameManager.getGameList();
for(int i=0;i<mList.size();i++){
Game mGame=mList.get(i);
Log.i(TAG,mGame.gameName+"---"+mGame.gameDescribe);
}
} catch (RemoteException e) {
e.printStackTrace();
}
} @Override
public void onServiceDisconnected(ComponentName name) { }
};
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection); }
}
绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序
打印出了远程服务端的所有的游戏,这样我们就成功的在客户端通过AIDL来调用远程服务端的方法了。
https://github.com/henrymorgen/MoonAIDL2
Android IPC机制(三)使用AIDL实现跨进程方法调用的更多相关文章
- Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用
在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法.可是我们能发现Messenger是以串行的方式来处理client ...
- Android中使用ContentProvider进行跨进程方法调用
原文同一时候发表在我的博客 点我进入还能看到很多其它 需求背景 近期接到这样一个需求,须要和别的 App 进行联动交互,比方下载器 App 和桌面 App 进行联动.桌面的 App 能直接显示下载器 ...
- Service官方教程(11)Bound Service示例之2-AIDL 定义跨进程接口并通信
Android Interface Definition Language (AIDL) 1.In this document Defining an AIDL Interface Create th ...
- 不依赖AIDL的跨进程通信
http://blog.csdn.net/lmj623565791/article/details/38461079 如果知道AIDL和binder的原理,可以简单写一个不依赖AIDL的跨进程通信 不 ...
- Wayland中的跨进程过程调用浅析
原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Composi ...
- Android IPC机制之AIDL
什么是AIDL AIDL:Android Interface Definition Language,即Android接口定义语言. Android系统中的进程之间不能共享内存,因此,需要提供一些机制 ...
- Android IPC机制全解析<一>
概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...
- Android IPC机制基础
概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Bi ...
- android IPC 机制 (开发艺术探索)
一.IPC 机制介绍 IPC是Inter-Process Communication的缩写,含义就是进程间通信或者跨进程通信,是指两个进程之间进行数据交换的过程.那么什么是进程,什么是线程,进程和线程 ...
随机推荐
- 爬虫不过如此(python的Re 、Requests、BeautifulSoup 详细篇)
网络爬虫(又被称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本. 爬虫的本质就是一段自动抓取互联网信息的程序,从网络获取 ...
- 【PHP篇】数组
1.简介:数组存储方式是键值对 2.声明:$数组变量名=array(2,3,9,3,“546”,“yy”=>”hhhh”,100=>”uu100”): 3.下标注意:可为“字符串”或者整数 ...
- 1 分钟教会你用 Spring Boot 发邮件
Spring Boot 提供了一个发送邮件的简单抽象,使用的是下面这个接口. org.springframework.mail.javamail.JavaMailSender Spring Boot ...
- iOS学习——更改导航栏的返回按钮的标题与颜色
转载自:修改navigationController返回按钮颜色和文字 今天在做项目时遇到这个问题,试了很多方法都失败了.最后终于找到正确的方案了,在这里分享给大家. 引言 在iOS开发过程中,Nav ...
- ExternalException (0x80004005): 无法执行程序
今天更新系统上传到阿里云服务器,报错如下: “/”应用程序中的服务器错误. 组策略阻止了这个程序.要获取详细信息,请与系统管理员联系. 说明: 执行当前 Web 请求期间,出现未经处理的异常.请检查堆 ...
- Github page搭建博客使用自定义插件的方法
Github page的后台程序是由Jekyll搭建,但由于Github的保护措施,非认证的plugin一般不会被Github page支持,但可以使用一些小技巧来绕过屏蔽. 以个人page为例,个人 ...
- Java的优点
前几天面试被问到:“Java的优点有哪些?”,当时只回答了跨平台和解释型两点,做的并不是太好,所以今天小编就总结一下Java的几大优点,增加自己的知识储备. 1.跨平台性: Java通过自带的JVM实 ...
- Python xlrd xlwt 读取写入Excel.
import xlrd import xlwt #读取 xlrd.Book.encoding = "gbk" wb = xlrd.open_workbook(filename='s ...
- 基于Electron+.NET Core的前后端分离的跨平台桌面应用
Web做界面比原生桌面界面开发速度真心要快很多,而且组件也多. 分析: 1..NET Core和Electron都是跨平台的. 2.NET Core做后端很方便,但是没有GUI,Electron做桌面 ...
- Log4Net 生成多个文件、文件名累加解决方法
Log4Net 生成多个文件.文件名累加解决方法 项目中的WCF服务里采用Log4Net用来记录异常日志,但部署后,生成的日志会出现多个累加文件,如下图: WCF是寄宿在IIS上,包含了5个SVC服务 ...