AIDL简单使用
来源:互联网 发布:java 正态分布随机数 编辑:程序博客网 时间:2024/06/05 03:47
AIDL(Android Interface Definition Language),Android接口定义语言。一般利用AIDL来进行进程间通信,大概流程如下:
1、服务端进程创建一个Service,供客户端进程来连接,通过创建AIDL文件定义好接口,然后Android Studio会自动帮我们生成对应AIDL的.java文件,然后服务端实现接口里的方法,并在onBind方法中返回自定义Binder对象,Binder相当于是服务端和客户端通信的桥梁。
2、客户端需要把服务端的AIDL文件复制到客户端app的工程下,切记包名也要一样,如果在调用AIDL的方法中使用到了自定义的类,也一样需要把该类的.java文件一并复制过来,同样,包名也必须一致,有了服务端的AIDL文件,我们只需要绑定服务端的Service,在绑定成功后,拿到服务端onBind方法返回的Binder对象进行一下转换,就能调用服务端实现的方法了。这样就实现了两个进程间的通信。
接下来看具体实现(为了方便,在同一个app中让Service运行在另外一个进程中,然后通过主进程去和该Service通信,这和两个app之间的通信实质上是一样的,只是省去了复制AIDL文件和自定义类文件了):
这里使用Android Studio来编写,右键->新建一个名为IPersonService的AIDL,这时IDE会自动帮我们在main包下建立一个aidl的包,里面放着刚才IPersonService.aidl文件:
// IPersonService.aidlpackage com.example.androidipc;// Declare any non-default types here with import statementsimport com.example.androidipc.Person;interface IPersonService { List<Person> getPerson(); void addPerson(in Person p);}IPersonService.aidl中声明了两个方法,getPerson获取所有person list,addPerson往集合中添加一个person对象,在addPerson方法的参数前面有一个in,是说明我们这个参数是属于输入型的。再看看Person.aidl:
// Person.aidlpackage com.example.androidipc;parcelable Person;Person对应的.java文件:
package com.example.androidipc;import android.os.Parcel;import android.os.Parcelable;/** * Created by Rainbow556 on 11/22/2015. */public class Person implements Parcelable{ private String name; private int age; public Person(String name,int age){ this.name=name; this.age=age; } protected Person(Parcel in) { name=in.readString(); age=in.readInt(); } public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @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); } @Override public String toString() { return name+" , "+age; } public String getName() { return name; }}上一篇博客说过,支持跨进程传输的类型只有基本数据类型和Android中特定的某些类,如果要传输自定义类的话,这个类必须要实现Parcelable接口。
下面是工程结构:
有一点要注意,就算IPersonService和Person位于同一个包下,但在IPersonService中还是要显示的导入Person类,否则会提示找不到类。
接着看Service的代码:
public class PersonService extends Service { private List<Person> persons=new ArrayList<>(); public PersonService() { } @Override public void onCreate() { super.onCreate(); Person p=null; for (int i=0;i<3;i++){ p=new Person("lx"+i,18+i); persons.add(p); } } @Override public IBinder onBind(Intent intent) { return new PersonBinder(); } public class PersonBinder extends IPersonService.Stub{ @Override public List<Person> getPerson() throws RemoteException { return persons; } @Override public void addPerson(Person person) throws RemoteException { persons.add(person); } @Override public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {// String packageName = null;// //拿到调用者的包名,可以做权限验证// String[] packages = PersonService.this.getPackageManager().// getPackagesForUid(getCallingUid());// if (packages != null && packages.length > 0) {// packageName = packages[0];// }// if (!ALLOW_PACKAGE.equals(packageName)) {// return false;// } return super.onTransact(code, data, reply, flags); } }}可以看到在Service中自定义个了PersonBinder继承了IPersonService.Stub,并重写了三个方法,注意一下onTransact方法,在这个方中可以对调用者进行自定义的权限验证,如果返回false,则调用者会调用失败。
再看activity中绑定Service,调用aidl中的方法:
public class AIDLActivity extends Activity { IPersonService mService; TextView tv; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aidl); ServiceConnection mServiceConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IPersonService.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { } }; Intent i=new Intent(this,PersonService.class); bindService(i,mServiceConnection,BIND_AUTO_CREATE); tv = (TextView) findViewById(R.id.tv); } public void getPersonList(View v){ try { tv.setText(mService.getPerson().toString()); } catch (RemoteException e) { e.printStackTrace(); } } public void addPerson(View v){ Person p=new Person("lj",22); try { mService.addPerson(p); tv.setText(mService.getPerson().toString()); } catch (RemoteException e) { e.printStackTrace(); } }}在activity中建立一个ServiceConnection,去绑定服务,在绑定成功后调用IPersonService.Stub.asInterface方法把传递过来的IBinder转换成IPersonService对象,这样就可以调用服务端aidl中的方法了,大概流程就是这样。
- AIDL简单使用Demo
- AIDL的简单使用
- AIDL简单使用
- aidl的简单使用
- AIDL简单的使用
- AIDL的简单使用
- AIDL简单使用
- AIDL的简单使用
- Android aidl简单使用
- aidl的简单使用
- AIDL简单使用
- 简单的AIDL的使用
- 一个AIDL的简单使用
- android AIDL的简单使用
- Android Service AIDL 简单使用
- aidl简单的使用步骤
- Aidl 的使用 简单 通讯
- Android AIDL的简单使用
- 【FastDev4Android框架开发】CardView完全解析与RecyclerView结合使用(三十二)
- 第一天
- c++友元类及友元函数
- Ctrip DAL Database Sharding Support
- 我要开始一个小项目
- AIDL简单使用
- 项目开发之分析业务实体
- Java并发编程:线程池的使用
- 日报2015/11/23(第一行代码读书笔记)
- ROM、SDRAM、RAM、DRAM、SRAM、FLASH的区别
- ThreadLocal源码解析
- [014]Java设计模式1——观察者模式
- cocos2dx v3.x box2d DrawDebugData 后置问题
- c++栈之带括号的四则运算