欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android Studio创建AIDL文件并实现进程间通讯实例

程序员文章站 2022-10-24 17:49:24
在android系统中,跨进程通信是非常普遍的事情,它用到了binder机制处理进程之间的交互。binder机制会开放一些接口给java层,供android开发工程师调用进...

在android系统中,跨进程通信是非常普遍的事情,它用到了binder机制处理进程之间的交互。binder机制会开放一些接口给java层,供android开发工程师调用进程之间通信。这些接口android封装到了aidl文件里,当我们项目用到跨进程通信时可以创建.aidl文件,.aidl文件可以协助我们达到跨进程的通信。下面简单介绍用androidstudio创建aidl文件的过程。

a.新建aidl文件

1.项目文件夹右键---> new --->选择aidl

Android Studio创建AIDL文件并实现进程间通讯实例

2.自定义一个接口名称

Android Studio创建AIDL文件并实现进程间通讯实例

3.创建之后我们看到了xxx.aidl文件,然后编辑自己项目需要实现的方法,这里很简单就获取一个字符串的方法getallname。

Android Studio创建AIDL文件并实现进程间通讯实例

4.写好之后,我们需要重新rebuild,完后在项目build/generated/source/aidl/debug/包名 目录下就看到了系统为我们生成的以刚才.aidl文件名命名的java文件。

Android Studio创建AIDL文件并实现进程间通讯实例

该java文件系统会自动生成代码:

stub:描述了一个java服务,对应是一个远程的service。

proxy:描述了一个java服务的代理对象,在client端就会得到这个对象。

这两者都实现了ipersonmanager接口。

asinterface:将java服务的代理对象即一个binderproxy封装成了一个ipersonmanager.stub.proxy对象,实现了ipersonmanager接口。

ontransact:负责接收分发进程间的通信。它首先会收到client发来的请求,不同的方法进入相应的case代码中,然后交给stub的子类去处理事件,例如 java.lang.string _result = this.getallname();   这里的this就可以让它的子类去接收该请求并处理。
ibinder的transact方法:用来发送进程间的请求。

b.利用aidl实现进程间的通讯

一:接口文件中只含有基础数据类型

如上aidl文件,ipersonmanager中只用到了基本数据类型,此时要完善server端的小项目,还需要新建一个service。
server端代码如下

public class personservice extends service { 
 
  private static string names = "alice & iland"; 
  public personbinder mpersonbinder; 
  @override 
  public void oncreate() { 
    super.oncreate(); 
    mpersonbinder = new personbinder(); 
  } 
 
  @override 
  public ibinder onbind(intent intent) { 
    return mpersonbinder; 
  } 
  public class personbinder extends ipersonmanager.stub{ 
 
    @override 
    public string getallname() throws remoteexception { 
      return names; 
    } 
  } 
 
} 

继承系统的service,并建立一个内部类继承ipersonmanager.stub,这里很简单,当客户端请求要获取名字时我们这里把names给到客户端。

client端代码如下

public class mainactivity extends appcompatactivity implements view.onclicklistener{ 
  private static final string tag = "mainactivity"; 
  private button btnget; 
  private edittext etshow; 
  public ipersonmanager mipersonmanager; 
  serviceconnection sc = new serviceconnection() { 
    @override 
    public void onserviceconnected(componentname name, ibinder service) { 
      log.i(tag, "onserviceconnected: "); 
      mipersonmanager = ipersonmanager.stub.asinterface(service); 
    } 
 
    @override 
    public void onservicedisconnected(componentname name) { 
      log.i(tag, "onservicedisconnected: "); 
      mipersonmanager = null; 
    } 
  }; 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.activity_main); 
    btnget = (button) findviewbyid(r.id.btn_getname); 
    etshow = (edittext) findviewbyid(r.id.et_allnamef); 
    btnget.setonclicklistener(this); 
 
    intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); 
    intent.setpackage("com.ly.testaidlserver"); 
    bindservice(intent,sc, service.bind_auto_create); 
  } 
 
  @override 
  public void onclick(view v) { 
    switch (v.getid()){ 
      case r.id.btn_getname: 
        string names = null; 
        try { 
          if (mipersonmanager!=null) 
            names = mipersonmanager.getallname(); 
        } catch (remoteexception e) { 
          e.printstacktrace(); 
        } 
        etshow.settext(names); 
        break; 
      default: 
        break; 
    } 
  }@override 
  protected void ondestroy() { 
    super.ondestroy(); 
    unbindservice(sc); 
  } 
 
} 

在onserviceconnected方法中拿到ipersonmanager的代理对象,最终获取到 alice & ilan,与服务端数据一致。

注意:

1.bindservice方法在5.0以后做出改变,隐式意图需要设置package 或者 commponent,直接定义一个action是报异常的。

intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); 
intent.setpackage("com.ly.testaidlserver");
bindservice(intent,sc, service.bind_auto_create); 

2.我们需要把server端的aidl文件复制到client端,在client中存放aidl的文件夹也需要跟server端包名一致。

如图:

Android Studio创建AIDL文件并实现进程间通讯实例

Android Studio创建AIDL文件并实现进程间通讯实例

上图为aidl文件在server端存放的路径,下图为复制到client端aidl文件的路径,这里要保持一致,因此client端需要针对server端的包名新建一个package。

3.当我们启动项目的时候,如果在activity中ipersonmanager找不到报出异常,请在app的build.gradle中添加aidl文件指名目录,如本例中添加,

  sourcesets{
    main {
      aidl.srcdirs = ['src/main/aidl','src/main/java']
    }
  }

二:接口文件中含有复杂数据类型、

1.新建一个person.aidl     内容非常简单
parcelable person;

2.新建一个person实体类,为了能在进程间进行通信必须实现parcelable接口。

3.在ipersonmanager中添加了一个方法,这里注意用到的person类必须将包名improt进去。

4.将ipersonmanager.aidl、person.aidl、person.java复制到客户端的aidl包下。

5.查看是否需要修改build.gradle中sourcesets设置

代码基本没有变化:

person.java

public class person implements parcelable { 
  string name; 
  int age; 
 
  public person(string name, int age) { 
    this.name = name; 
    this.age = age; 
  } 
 
  public static final creator<person> creator = new creator<person>() { 
    @override 
    public person createfromparcel(parcel in) { 
      return new person(in.readstring(), in.readint()); 
    } 
 
    @override 
    public person[] newarray(int size) { 
      return new person[size]; 
    } 
  }; 
 
  @override 
  public int describecontents() { 
    return 0; 
  } 
 
  @override 
  public void writetoparcel(parcel dest, int flags) { 
    dest.writestring(name); 
    dest.writeint(age); 
  } 
 
  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; 
  } 
} 

ipersonmanager.aidl

interface ipersonmanager { 
  string getallname(); 
  list<person> getpersonlist(); 
} 

server

public class personservice extends service { 
 
  private list<person> persons = new arraylist<person>(); 
  public personbinder mpersonbinder; 
  @override 
  public void oncreate() { 
    super.oncreate(); 
    mpersonbinder = new personbinder(); 
    person p1 = new person("alice",23); 
    persons.add(p1); 
    person p2 = new person("iland",18); 
    persons.add(p2); 
  } 
 
  @override 
  public ibinder onbind(intent intent) { 
    return mpersonbinder; 
  } 
  public class personbinder extends ipersonmanager.stub{ 
 
    @override 
    public string getallname() throws remoteexception { 
      return ""; 
    } 
 
    @override 
    public list<person> getpersonlist() throws remoteexception { 
      return persons; 
    } 
  } 
} 

clent

public class mainactivity extends appcompatactivity implements view.onclicklistener{ 
  private static final string tag = "mainactivity"; 
  private button btnget; 
  private edittext etshow; 
  public ipersonmanager mipersonmanager; 
  serviceconnection sc = new serviceconnection() { 
    @override 
    public void onserviceconnected(componentname name, ibinder service) { 
      log.i(tag, "onserviceconnected: "); 
      mipersonmanager = ipersonmanager.stub.asinterface(service); 
    } 
 
    @override 
    public void onservicedisconnected(componentname name) { 
      log.i(tag, "onservicedisconnected: "); 
      mipersonmanager = null; 
    } 
  }; 
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    setcontentview(r.layout.activity_main); 
    btnget = (button) findviewbyid(r.id.btn_getname); 
    etshow = (edittext) findviewbyid(r.id.et_allnamef); 
    btnget.setonclicklistener(this); 
 
    intent intent = new intent("com.ly.testaidlserver.aidl.aidl_service"); 
    intent.setpackage("com.ly.testaidlserver"); 
    bindservice(intent,sc, service.bind_auto_create); 
  } 
 
  @override 
  public void onclick(view v) { 
    switch (v.getid()){ 
      case r.id.btn_getname: 
        arraylist<person> persons = null; 
        try { 
          if (mipersonmanager!=null) 
            persons = (arraylist<person>) mipersonmanager.getpersonlist(); 
        } catch (remoteexception e) { 
          e.printstacktrace(); 
        } 
        string result = ""; 
        for (person person : persons){ 
          result = result+person.getname()+"__"+person.getage(); 
        } 
        etshow.settext(result); 
        break; 
      default: 
        break; 
    } 
  }@override 
  protected void ondestroy() { 
    super.ondestroy(); 
    unbindservice(sc); 
  } 
 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。