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

在上一篇文章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 {
  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来调用远程服务端的方法了。

github源码下载

时间: 2024-12-28 01:32:24

Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用的相关文章

Android中使用ContentProvider进行跨进程方法调用

原文同时发表在我的博客 点我进入还能看到更多 需求背景 最近接到这样一个需求,需要和别的 App 进行联动交互,比如下载器 App 和桌面 App 进行联动,桌面的 App 能直接显示下载器 App 内的下载任务进度和状态. 寻找解决方案 从需求上知道了,主要问题在如何解决跨进程的通信上边. AIDL AIDL 即 Android Interface Definition Language的缩写,是专为 Android 中跨进程通信接口的描述语言.优缺点很明显,优点是稳定,快,Android 专

Android IPC机制(三):浅谈Binder的使用

一.前言 在上一篇博客Android IPC机制(二):AIDL的基本用法中,笔者讲述了安卓进程间通讯的一个主要方式.利用AIDL进行通讯.并介绍了AIDL的基本用法. 事实上AIDL方式利用了Binder来进行跨进程通讯.Binder是Android中的一种跨进程通讯方式.其底层实现原理比較复杂.限于笔者水平,不能展开详谈.所以这篇文章主要谈谈以AIDL为例,谈谈Binder的用法. 二.原理 上一篇文章中创建了一个IMyAidl.aidl文件,即接口文件,随即编译了该文件.生成了一个.jav

Android IPC机制(五)用Socket实现跨进程聊天程序

相关文章: Android IPC机制(一)开启多进程 Android IPC机制(二)用Messenger进行进程间通信 Android IPC机制(三)在Android Studio中使用AIDL实现跨进程方法调用 Android IPC机制(四)用ContentProvider进行进程间通信 1.Socket简介 Socket也称作"套接字",是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中通信.它分为流式套接字和

Android——IPC机制(一)IPC概念以及Binder机制

由于IPC机制牵扯的东西比较多,所以这里将分为一个系列进行总结 主要介绍内如如下: IPC简介 Android中的多进程模式 开启多进程模式 多进程模式的运行机制 IPC基础概念介绍 Serializable接口 Parcelable接口 Binder Android中的IPC方式 使用Bundle 使用文件共享 使用Messenger 使用AIDL 使用ContentProvider 使用Socket Binder连接池 选用合适的IPC方式 IPC简介 IPC是Inter-Process C

Android IPC机制—Binder的工作机制

进程和线程的关系 IPC机制即为跨进程通信,是inter-Process Communication的缩写.是指两个进程之间进行通信.在说进程通信之前,我们的弄明白什么是线程,什么是进程.进程和线程是两个截然不同的概念.按照操作系统中的描述,线程是CPU调度的最小单位,同时线程也是一种有限的系统资源.而进程一般是指一个执行单元,在pc端或者移动端上是指一个程序或者一个应用.一个进程中可以包含一个或者是多个线程.所以他们的关系应该是包含和被包含的关系. 跨进程的种类 在Android中跨进程通信的

Wayland (三) Wayland中的跨进程过程调用浅析 [FW]

原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个參考实现.Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能,在作用上类似于Android中的Binder.与Binder不同的是,在Wayland中Client和Server底层通过domain socke

Wayland中的跨进程过程调用浅析

原文地址:http://blog.csdn.net/jinzhuojun/article/details/40264449 Wayland协议主要提供了Client端应用与Server端Compositor的通信机制,Weston是Server端Compositor的一个参考实现.Wayland协议中最基础的是提供了一种面向对象的跨进程过程调用的功能,在作用上类似于Android中的Binder.与Binder不同的是,在Wayland中Client和Server底层通过domain socke

Android IPC机制全解析&lt;一&gt;

概要 多进程概念及多进程常见注意事项 IPC基础:Android序列化和Binder 跨进程常见的几种通信方式:Bundle通过Intent传递数据,文件共享,ContentProvider,基于Binder的AIDL和Messenger以及Socket. Binder连接池 各种进程间通信方式的优缺点及适用场景 IPC是 Inter-Process Communication的缩写,意为进程间通信或跨进程通信,是指两个进程之间进行数据交换的过程. 线程是CPU调度的最小单元,同时线程是一种有限

Android Studio中使用AIDL进行进程间通信

什么是AIDL aidl是 Android Interface definition language的缩写,也就是安卓接口定义语言 为什么要有AIDL AIDL允许你定义客户端与服务端达成一致的程序接口使用进程间通信相互交流. 在Android上面,一个进程不能正常的访问另一个进程的内存. 所以说,他们需要分解他们的对象为操作系统可以理解的基本单位,然后为你把这些对象按次序跨越进程边界 ,书写这些代码是单调冗长的,所以android使用AIDL为你处理这个问题. 注意:使用AIDL只有在你允许