Android AIDL入门篇

一、概述
由于Android中两个进程间无法直接进行通信,但是有时候又会有这样的需求,所以在此,我们引入了AIDL(Android接口定义语言),目的是为了实现进程间通信,尤其是在涉及多进程并发情况下的进程间通信。这样我们就可以在一个进程访问另一个进程中的数据,甚至调用它的一些方法,当然,只能是特定的方法。

二、测试效果图
这里我们编写了一个测试案例实现在一个进程中调用另一个进程中的方法
这里写图片描述

三、核心代码

1.服务端
这里写图片描述

IMyAidl.aidl

// IMyAidl.aidl
package com.czhappy.aidldemo;

import com.czhappy.aidldemo.Person;

// Declare any non-default types here with import statements

interface IMyAidl {

    int add(int num1, int num2);

    List<Person> addPerson(in Person person);
}

Person.aidl

// IMyAidl.aidl
package com.czhappy.aidldemo;

parcelable Person;

IRemoteService.java

package com.czhappy.aidldemo;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Description:
 * User: chenzheng
 * Date: 2017/1/6 0006
 * Time: 11:41
 */
public class IRemoteService extends Service {

    private List<Person> persons;

    /**
     * 当客户端绑定到该服务时调用
     * @param intent
     * @return
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        persons = new ArrayList<Person>();
        return iBinder;
    }

    private IBinder iBinder = new IMyAidl.Stub(){

        @Override
        public int add(int num1, int num2) throws RemoteException {
            Log.e("tag", "收到的两个参数为:"+num1+"和"+num2);
            return num1+num2;
        }

        @Override
        public List<Person> addPerson(Person person) throws RemoteException {
            persons.add(person);
            return persons;
        }
    };
}

Person.java

package com.czhappy.aidldemo;

import android.os.Parcel;
import android.os.Parcelable;

/**
 * Description:
 * User: chenzheng
 * Date: 2017/1/6 0006
 * Time: 15:00
 */
public class Person implements Parcelable{

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person(Parcel source) {
        this.name = source.readString();
        this.age = source.readInt();
    }

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

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(name);
        dest.writeInt(age);

    }

    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel source) {
            return new Person(source);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2.客户端
这里写图片描述

其中IMyAidl.aidl和Person.aidl以及Person.java文件和服务端相同,特别注意的它们的包名都要完全一样,否则会报错。
MainActivity.java

package com.czhappy.aidlclient;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.EditText;

import com.czhappy.aidldemo.IMyAidl;
import com.czhappy.aidldemo.Person;

import java.util.List;

public class MainActivity extends AppCompatActivity {

    private EditText num1_et, num2_et, res_et;

    private IMyAidl iMyAidl;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //拿到了远程的服务
            iMyAidl = IMyAidl.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            //回收
            iMyAidl = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();
        bindService();
    }

    private void initView() {

        num1_et = (EditText) findViewById(R.id.num1_et);
        num2_et = (EditText) findViewById(R.id.num2_et);
        res_et = (EditText) findViewById(R.id.res_et);

    }

    public void doAdd(View view){

        int num1 = Integer.parseInt(num1_et.getText().toString());
        int num2 = Integer.parseInt(num2_et.getText().toString());

        try {
            //调用远程的服务
            int res = iMyAidl.add(num1, num2);
            res_et.setText(res+"");
        } catch (RemoteException e) {
            e.printStackTrace();
        }


    }

    public void getPersons(View view){

        try {
            List<Person> list = iMyAidl.addPerson(new Person("zhangsan", 21));
            Log.e("tag", list.toString());
        } catch (RemoteException e) {
            e.printStackTrace();
        }

    }



    /**
     * 绑定服务
     */
    private void bindService() {
        Intent it = new Intent();
        //5.0新版本必须显示Intent启动绑定服务
        it.setComponent(new ComponentName("com.czhappy.aidldemo","com.czhappy.aidldemo.IRemoteService"));
        bindService(it, conn, Context.BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

四、测试结果
点击计算按钮时后台打印:
这里写图片描述
多次点击获取集合按钮时后台打印:
这里写图片描述

五、注意事项
1.服务器端和客户端的aidl文件的包名和类名以及里面的内容都是完全一样的,否则会报java.lang.SecurityException: Binder invocation to an incorrect interface这种异常
2.先运行服务器端程序启动了服务,才能进行客户端demo的测试
3.服务器端记得添加service配置

<service android:name="com.czhappy.aidldemo.IRemoteService"
            android:exported= "true"
            android:process=":remote"/>

六、源码下载
http://download.csdn.net/detail/chenzheng8975/9730820

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值