Android 进程间通信(IPC)---AIDL入门

来源:互联网 发布:python web开发入门 编辑:程序博客网 时间:2024/06/10 03:16

AIDL简介

  AIDL是 Android Interface Definition Language的缩写。AIDL 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行 IPC的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

这里我们需要建立两个工程,一个作为客户端,另外一个作为服务端。

一、建立客户端的工程,结构如下:

这里写图片描述

首先新建一个package(com.zjt.myaidl)。在该package中新建一个名为IMyService.aidl的文件。如下:

package com.zjt.myaidl;import com.zjt.myaidl.Person;interface IMyService{   List<Person> getPerson();   void addPerson(in Person person);}

说明:

  1. AIDL支持java基本类型如: int, long,double, char, boolean等。其他类型必须要用import 导入,即使是在同一个包中。比如本工程中IMyService和Person是在同一个包中。

  2. 另外,接口中的参数除了aidl支持的类型,其他类型必须标识其方向:到底是输入还是输出抑或两者兼之,用in,out或者inout来表示,上面的代码我们用in标记,因为它是输入型参数。

  3. 如果需要访问自定义对象,还需要建立对象的aidl文件,这里我们由于使用了自定义对象Person,所以还需建立一个Person.aidl文件。

由于使用了自定义对象Person,那么需要对该对象进行序列化。这里我们让Person 类实现Parcelable接口。

Person.java:

public class Person implements Parcelable {    private String name ;    private int age;    private String sex;    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;    }    public String getSex() {        return sex;    }    public void setSex(String sex) {        this.sex = sex;    }    public Person(String name,int age , String sex){        this.name = name;        this.age = age;        this.sex = sex;    }    public Person(){    }    @Override    public int describeContents() {        // TODO Auto-generated method stub        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        // TODO Auto-generated method stub        Log.e("xxx", "writeToParcel");        //这里字段写的顺序要和下面读的顺序要一致,从name、age到sex        dest.writeString(name);        dest.writeInt(age);        dest.writeString(sex);    }    public static final Parcelable.Creator<Person> CREATOR = new Creator<Person>() {        @Override        public Person[] newArray(int size) {            // TODO Auto-generated method stub            return new Person[size];        }        @Override        public Person createFromParcel(Parcel source) {            // TODO Auto-generated method stub            Person person = new Person();            //这里字段读的顺序要和下面写的顺序要一致,从name、age到sex            person.name = source.readString();            person.age = source.readInt();            person.sex = source.readString();            return person;        }    };}

Person.aidl文件很简单,如下所示,要注意的是 这里parcelable是个类型,首字母是小写的,和Parcelable接口不是一个东西。

package com.zjt.myaidl;parcelable Person;

二、建立服务端的Service,MyService.java文件如下:

public class MyService extends Service{    //private IBinder mBinder;    private List<Person> mPersons = new ArrayList<Person>();    @Override    public IBinder onBind(Intent intent) {        // TODO Auto-generated method stub        return mBinder;    }    @Override    public void onCreate() {        // TODO Auto-generated method stub        super.onCreate();        Person mPerson = new Person("zjt", 28, "male");        mPersons.add(mPerson);    }    //在这里实现aidl中的抽象方法    private final IMyService.Stub mBinder = new IMyService.Stub() {        @Override        public List<Person> getPerson() throws RemoteException {            // TODO Auto-generated method stub            synchronized (mPersons) {                return mPersons;            }        }        @Override        public void addPerson(Person person) throws RemoteException {            // TODO Auto-generated method stub            synchronized (mPersons) {                if(!mPersons.contains(person)){                    mPersons.add(person);                }            }        }    };

三、在AndroidManifest.xml文件中声明Service:

 <service android:name="com.example.myaidlactivity.MyService"     android:process=":remote"     android:enabled="true">     <intent-filter >         <category                       android:name="android.intent.category.DEFAULT"/>        <action                 android:name="com.example.myservice.action"/>            </intent-filter>        </service>

说明:上述的 是为了能让其他apk通过action来隐式启动bindService,通过隐式调用的方式来起activity或者service,需要把category设为default,这是因为,隐式调用的时候,intent中的category默认会被设置为default。

以上完成后,新建一个工程来充当客户端。

四、新建一个工程来充当客户端。
1.新建一个名为TestAidlClient的工程充当客户端。把上面的服务端中整个package(com.zjt.myaidl)copy到本项目的src目录下,

工程结构如下:

这里写图片描述

这个时候,客户端com.zjt.myaidl包是和服务端工程完全一样的。

MainActivity.java:

public class MainActivity extends Activity {    private IMyService myService;    private List<Person> mPersons = new  ArrayList<Person>();    private Button bindService;    private final static String SERVICE_ACTION = "com.example.myservice.action";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        bindService = (Button) findViewById(R.id.bindService);        bindService.setOnClickListener(new OnClickListener() {            @Override            public void onClick(View v) {                // TODO Auto-generated method stub                Intent mIntent = new Intent(SERVICE_ACTION);                bindService(mIntent, mServiceConnection, BIND_AUTO_CREATE);            }        });    }    private ServiceConnection mServiceConnection = new ServiceConnection() {        @Override        public void onServiceDisconnected(ComponentName name) {            // TODO Auto-generated method stub            myService = null;        }        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            // TODO Auto-generated method stub            //通过服务端onBind方法返回的binder对象得到IMyService的实例,得到实例就可以调用它的方法了            myService = IMyService.Stub.asInterface(service);            try {                //通过IMyService接口来添加Person对象                myService.addPerson(new Person("wj", 26, "female"));                mPersons = myService.getPerson();                for(int i=0; i<mPersons.size();i++){                    Person person = mPersons.get(i);                    Log.e("----", "name = "+person.getName()+"\n age = "+person.getAge()+"\n sex = "+person.getSex());                    Log.d("...", ".............");                }            } catch (Exception e) {                // TODO: handle exception            }        }    };}

运行结果如下:
这里写图片描述

可以看到我们通过aidl的方式获取到另一apk的数据。

源码下载地址:http://download.csdn.net/detail/zhujiangtaotaise/9384987

1 0
原创粉丝点击