Android 进程间通信(AIDL)

在Android平台,一个进程通常不能访问另一个进程的内存空间,所以要想对话,需要将对象分解成操作系统可以理解的基本单元,并且有序的通过进程边界。通过代码来实现这个数据传输过程是冗长乏味的,Android提供了AIDL工具来处理这项工作。
AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码。如果在一个进程中(例如Activity)要调用另一个进程中(例如Service)对象的操作,就可以使用AIDL生成可序列化的参数。

定义AIDL接口

AIDL接口文件,和普通的接口内容没有什么特别,只是它的扩展名为.aidl。保存在src目录下。如果其他应用程序需要IPC,则那些应用程序的src也要带有这个文件。Android SDK tools就会在gen目录自动生成一个IBinder接口文件。service必须适当地实现这个IBinder接口。那么客户端程序就能绑定这个service并在IPC时从IBinder调用方法。

注意:每个aidl文件只能定义一个接口,而且只能是接口的声明和方法的声明。

我们举例说明:首先我们做一个在一个项目里开启多进程的例子。

1.项目工程列表如下:

这里写图片描述
MainActivity是运行在主进程的,ProcessService是运行在另一个进程中(实现方式看我的博客 Android 多进程基础)。

2.实现.aidl文件

接口描述文件
a、导入的包名
b、如果有使用Object对象,需要该对象 implement Parcelable 接口,并且需要导入该接口包名+类名;
如果是primitive type 不需要这步。
c、定义方法名称。
d、所有的.aidl文件已经需要传递的对象接口需要在Service 与Client中各一份

IStockService.aidl文件

package com.example.processtest.aidl;
import com.example.processtest.aidl.Person;
interface IStockService {
  double getResult(double a,double b);
  com.example.processtest.aidl.Person getPerson();
}

如果aidl文件中需要传递Object对象,需要添加对应的.aidl文件
Person.aidl文件
a、定义该对象Data,并实现Parcelable
b、添加Data.aidl文件,并采用如下方式编写导入Data
c、需要在服务端和 客户端都添加 Data.aidl与 Data.java文件 并且需要一致。

package com.example.processtest.aidl;
parcelable Person;

添加 对应的Object类,并且实现Parcelable接口

public class Person implements Parcelable {
    private String name;
    private String age;
    public Person(){

    }
    private Person(Parcel in){
        readFromParcel(in);
    }

    public void readFromParcel(Parcel in)
    {
        name = in.readString();        
        age = in.readString();
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
 public static final Parcelable.Creator<Person> CREATOR=new Parcelable.Creator<Person>() {

    @Override
    public Person createFromParcel(Parcel source) {
        // TODO 自动生成的方法存根
        return new Person(source);
    }

    @Override
    public Person[] newArray(int size) {
        // TODO 自动生成的方法存根
        return new Person[size];
    }
};
    @Override
    public int describeContents() {
        // TODO 自动生成的方法存根
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        // TODO 自动生成的方法存根
        dest.writeString(name);
        dest.writeString(age);
    }

}

3.在Service中实现.aidl 接口

实际实现的接口是在 gen中自动生成的 IaidlData.java的抽象内部类 Stub。
创建好.aidl文件后,刷新项目,在gen包对应的包下会出现与aidl文件相同的Java文件

AIDL工具生成的Java文件中:
public static abstract class Stub extends android.os.Binder implements com.example.processtest.aidl.IStockService //静态抽象内部类

private static class Proxy implements com.example.processtest.aidl.IStockService //AIDL服务代理类

public double getResult(double a, double b) throws android.os.RemoteException //AIDL公布出的接口,就是我们定义的接口方法。

AIDL只是一个契约,我们需要一个服务来提供服务。

提供服务的类ProcessService

public class ProcessService extends Service {
private class IStockServiceImp extends IStockService.Stub{

    @Override
    public double getResult(double a, double b) throws RemoteException {
        // TODO 自动生成的方法存根
        return a+b;
    }

    @Override
    public Person getPerson() throws RemoteException {
        // TODO 自动生成的方法存根
        Person person=new Person();
        person.setAge("20");
        person.setName("zhangsan");
        return person;
    }

}
    @Override
    public IBinder onBind(Intent intent) {
        // TODO 自动生成的方法存根
        return new IStockServiceImp();
    }
 @Override
    public boolean onUnbind(Intent intent) {
        // TODO 自动生成的方法存根
        //关闭服务所在的进程
         android.os.Process.killProcess(android.os.Process.myPid());
        return super.onUnbind(intent);
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // TODO 自动生成的方法存根
        Log.d("xxx",
                android.os.Process.myPid() + ";"
                        + Tools.getCurProcessName(getApplicationContext()));
        Log.d("xxS", MyApplication.name);
        return super.onStartCommand(intent, flags, startId);
    }
}

4.进程间的通信

public class MainActivity extends Activity {
    private IStockService service2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.d("xxM", android.os.Process.myPid() + "");
        Intent intent = new Intent(getApplicationContext(),
                ProcessService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
        Log.d("xxM", MyApplication.name);
    }

    ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            // TODO 自动生成的方法存根

        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            // TODO 自动生成的方法存根
            service2 = IStockService.Stub.asInterface(service);
            try {
                Log.d("xx", service2.getResult(5, 9) + "");
                Log.d("xxp", service2.getPerson().getAge() + ";"
                        + service2.getPerson().getName());
            } catch (RemoteException e) {
                // TODO 自动生成的 catch 块
                e.printStackTrace();
            }
        }
    };

    public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            finish();
//          退出程序时我们一般只调用finish()函数杀死当前Activity,Application退到幕后,由系统自动维护。
//          再次启动程序时就不会执行Application.onCreate(),而是直接执行Activity.onCreate()。

            //杀掉进程的方法
            android.os.Process.killProcess(android.os.Process.myPid());
            return true;
        }
        return false;
    };

    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    };
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值