iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android Studio创建AIDL文件并实现进程间通讯实例
  • 648
分享到

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

AndroidStudiostudio进程aidlAndroid 2022-06-06 01:06:45 648人浏览 安东尼
摘要

在Android系统中,跨进程通信是非常普遍的事情,它用到了Binder机制处理进程之间的交互。Binder机制会开放一些接口给Java层,供android开发工程师调用进程之

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); 
  } 
} 
您可能感兴趣的文章:Android使用AIDL方式实现播放音乐案例Android AIDL实现两个APP间的跨进程通信实例Android使用AIDL实现两个App间通信Android应用程序四大组件之使用AIDL如何实现跨进程调用Service使用Android studio创建的AIDL编译时找不到自定义类的解决办法Android 使用【AIDL】调用外部服务的解决方法基于Android AIDL进程间通信接口使用介绍Android程序设计之AIDL实例详解实例讲解Android中的AIDL内部进程通信接口使用Android多进程间采用AIDL方式进行通信


--结束END--

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

本文链接: https://www.lsjlt.com/news/21797.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作