android studio 跨进程,Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用...

本文首发于微信公众号「后厂技术官」

在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messenger是以串行的方式来处理客户端发来的信息,如果有大量的消息发到服务端,服务端仍然一个一个的处理再响应客户端显然是不合适的。另外,Messenger用来进程间进行数据传递但是却不能满足跨进程的方法调用,接下来我们来使用AIDL来实现跨进程方法调用,此前我们都是用Eclipse来实现的,这次我们看看在Android Studio中使用AIDL有什么不同。

1. 创建AIDL文件

我们将项目的目录结构调为Android模式,在java同级目录创建aidl文件夹,在文件夹中创建一个包名和应用包名一致的包

6cd6e6ee4c5fdfa488b4251437b0ebcf.png

我们先创建一个IGameManager.aidl的文件,这里面有两个方法分别是addGame和getGameList。(IGameManager.aidl)

package com.example.liuwangshu.moonaidl;

import com.example.liuwangshu.moonaidl.Game;

interface IGameManager{

ListgetGameList();

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 CREATOR = new Creator() {

@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。

2a2c65a24f2220ddf5cedec5fc101631.png

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 mGameList=new CopyOnWriteArrayList();

private Binder mBinder= new IGameManager.Stub() {

@Override

public List 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:

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 mList=iGameManager.getGameList();

for(int i=0;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方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序

6720dd245100c32fa8e353519181ffa8.png

打印出了远程服务端的所有的游戏,这样我们就成功的在客户端通过AIDL来调用远程服务端的方法了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值