Android学习之跨进程通信安卓接口定义语言AIDL(二)

接着刚刚的一篇讲下使用AIDL传递对象的过程,AIDL在不导入其他包的情况下支持如下几种数据类型:

1. 基本数据类型(boolean、char、byte、int、long、float、double),注意:不支持short

2. String和CharSequence

3. List和Map

4. Parcelable:

传递对象必须要实现序列化,ADIL中序列化对象的流程如下:

1)序列化对象

2)建立对象的.aidl文件,名称要一样

3)建立.aidl文件,手动导入对象,声明对象是in还是out

接上一篇,看下工程结构,IDemoAidlInterface大家不用管,是上一篇的内容:

先看下怎么序列化对象,首先创建Person类,实现Parcelable接口,具体方法怎么使用看注释

/**
 * 序列化
 *
 * @author yuzhentao
 */
public class Person implements Parcelable {

    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = 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;
    }

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

    /**
     * 内容接口描述,默认返回0就可以
     *
     * @return int
     */
    @Override
    public int describeContents() {
        return 0;
    }

    /**
     * 将对象序列化为一个Parcel对象
     * 将类的数据写入外部提供的Parcel中,打包需要传递的数据到Parcel容器保存,以便从Parcel容器获取数据
     *
     * @param dest:Parcel
     * @param flags:int
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
    }

    protected Person(Parcel in) {
        this.name = in.readString();
        this.age = in.readInt();
    }

    /**
     * 实例化静态内部对象CREATOR实现接口Parcelable.Creator
     */
    public static final Creator<Person> CREATOR = new Creator<Person>() {
        /**
         * 从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层
         * @param in:Parcel
         * @return Person
         */
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        /**
         *创建一个类型为<T>,长度为size的数组,供外部类反序列化本类数组使用
         * @param size:int
         * @return Person[]
         */
        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };

}
然后建立对象的.aidl文件,名称要一样,写法是

package yuzhentao.aidldemo;

//必须这样写
parcelable Person;
然后建立.aidl文件,手动导入对象,声明对象是in还是out,这里切记一定要手动导入一下

package yuzhentao.aidldemo;

//手动导入
import yuzhentao.aidldemo.Person;

interface IParcelableAidlInterface {

    //一定要带上in或者out,告诉这个Person是输入还是输出的
    List<Person> add(in Person person);

}

接着就是修改Service的内容了,将接口更改一下即可,然后返回ArrayList<Person>

/**
 * Aidl服务
 *
 * @author yuzhentao
 */
public class IDemoAidlService extends Service {

    private ArrayList<Person> personList;

    /**
     * 当客服端绑定到服务端时会执行
     *
     * @param intent:Intent
     * @return IBinder
     */
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
//        return iBinder;
        personList = new ArrayList<>();
        return iBinderPerson;
    }

//    private IBinder iBinder = new IDemoAidlInterface.Stub() {
//        @Override
//        public int add(int num1, int num2) throws RemoteException {
//            Log.e("yzt", "收到远程请求,输入的参数是:" + num1 + "和" + num2);
//            return num1 + num2;
//        }
//    };

    private IBinder iBinderPerson = new IParcelableAidlInterface.Stub() {
        @Override
        public List<Person> add(Person person) throws RemoteException {
            personList.add(person);
            return personList;
        }
    };

}

服务端准备完毕,接着将这些文件包括复制到客户端,包名一定要一样,看下客户端的结构,同样请无视IDemoAidlInterface


客户端同样将接口修改一下,点击时实例化一个ArrayList<Person>,通过接口的方法传递到服务端,打印Log看下结果

/**
 * 客户端
 * 获取服务端
 * .aidl必须和服务端的一样,包括包名,负责编译不通过
 * 如果有序列化对象,连同包名也必须一样
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    //    private IDemoAidlInterface iDemoAidlInterface;
    private IParcelableAidlInterface iParcelableAidlInterface;
    /**
     * 服务连接接口
     */
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {//连接服务时执行,ComponentName是bindService()指定的,IBinder是服务端的onBind()返回的
//            iDemoAidlInterface = IDemoAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了远程的服务的代理
            iParcelableAidlInterface = IParcelableAidlInterface.Stub.asInterface(service);//返回IDemoAidlInterface,拿到了远程的服务的代理
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {//断开服务时执行
//            iDemoAidlInterface = null;
            iParcelableAidlInterface = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        bindService();//绑定服务
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);//解绑服务
    }

    private void initView() {
//        final EditText etNum1 = (EditText) findViewById(R.id.edittext_num1_activity_main);
//        final EditText etNum2 = (EditText) findViewById(R.id.edittext_num2_activity_main);
//        final EditText etResult = (EditText) findViewById(R.id.edittext_result_activity_main);
        findViewById(R.id.button_activity_main).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
//                int num1 = Integer.parseInt(etNum1.getText().toString());
//                int num2 = Integer.parseInt(etNum2.getText().toString());
//                String result;
//                try {
//                    result = iDemoAidlInterface.add(num1, num2) + "";//调用远程的服务
//                    etResult.setText(result);
//                } catch (RemoteException e) {
//                    e.printStackTrace();
//                    etResult.setText("发生错误");
//                }
                try {
                    ArrayList<Person> personList = (ArrayList<Person>) iParcelableAidlInterface.add(new Person("yuzhentao", 25));
                    Log.e("yzt", personList.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * 绑定服务
     * alt+command+m:提取方法
     */
    private void bindService() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("yuzhentao.aidldemo", "yuzhentao.aidldemo.IDemoAidlService"));//显式Intent
        bindService(intent, conn, Context.BIND_AUTO_CREATE);//绑定服务
    }

}
03-14 14:38:49.319 31540-31540/yuzhentao.aidldemoclient E/yzt: [Person{name='yuzhentao', age=25}]

这里没有效果图,在此感谢下慕课网

Demo地址:http://download.csdn.net/detail/qq_23940659/9467044

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值