当前位置: 移动技术网 > IT编程>移动开发>Android > Android Studio创建AIDL文件并实现进程间通讯实例

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

综艺传奇方琼,啤酒 好处,农民工杀人伪造矿难

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

a.新建aidl文件

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

2.自定义一个接口名称

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

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

该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端包名一致。

如图:

上图为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); 
  } 
 
} 

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网