首页 > 系统 > Android > 正文

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

2019-12-12 03:09:23
字体:
来源:转载
供稿:网友

在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);   }  } 

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表