在上一篇文章Android IPC机制(二)用Messenger进行进程间通信中我们介绍了使用Messenger来进行进程间通信的方法,但是我们能发现Messenger是以串行的方式来处理客户端发来的信息,如果有大量的消息发到服务端,服务端仍然一个一个的处理再响应客户端显然是不合适的。另外,Messenger用来进程间进行数据传递但是却不能满足跨进程的方法调用,接下来我们来使用AIDL来实现跨进程方法调用,此前我们都是用Eclipse来实现的,这次我们看看在Android Studio中使用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 {  ListgetGameList();  void addGame(in Game game);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

在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);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

在这里不去讲怎么去实现Parcelable 接口,在上面的IGameManager.aidl文件中我们用到了Game这个类,所以我们也要创建Game.aidl,来申明Game实现了parcelable 接口。(Game.aidl)

package com.example.liuwangshu.moonaidl;parcelable Game;
  • 1
  • 2

这个时候我们重新编译程序,工程就会自动生成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 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;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

当然我们不要忘了这个服务端应该运行在另一个进程,在AndroidManifest.xml文件中配置service:

  <service android:name=".AIDLService" android:process=":remote">service>
  • 1

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"---"+mGame.gameDescribe);               }           } catch (RemoteException e) {               e.printStackTrace();           }       }       @Override       public void onServiceDisconnected(ComponentName name) {       }   };    @Override    protected void onDestroy() {        super.onDestroy();        unbindService(mServiceConnection);    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

绑定成功后我们创建了一个新的Game然后调用远程服务端的addGame方法将新游戏添加进去,然后调用循环将远端服务中的所有的游戏在打印出来,我们运行程序

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

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. Android(安卓)实现对话框圆角功能
  6. Android常见abd指令集
  7. 实现base64格式的amr音频文件在IOS、android微信内置浏览器的播
  8. android支持https通讯,交叉编译 libcurl libnghttp2 oponssl
  9. Android(安卓)6.0 新特性

随机推荐

  1. Android(安卓)adb “push pull”中文支持
  2. AsyncTask异步任务学习笔记(一、异步任务
  3. Android(安卓)studio 中文乱码问题解决
  4. [置顶] android Intent的Action、Categor
  5. [置顶] Android(安卓)View(二)-View的scr
  6. 30天入门 Android(安卓)开发, Google 与你
  7. android 模拟宏定义,实现Debug & Release
  8. 如何指定让Android的NDK工具编译出Releas
  9. Android项目导入出现The type java.lang.
  10. Android如何高效加载大图