Android进程间通信之AIDL(二)—— 简单使用

既然是进程间通信,肯定会有服务端和客户端

一、服务端

1、在服务端我们首先定义一个提供服务的AIDL接口文件:IMyAidlInterface.aidl以及根据需求自定义了一个Worker的数据类型,如下图:(注意aidl包与java包是在同一级目录)


aidl文件的书写方式很简单其中Worker.aidl内容如下:

// Worker.aidl
package com.zui.lib.data;

// 自定义数据类型
parcelable Worker;

IMyAidlInterface.aidl如下:

// IMyAidlInterface.aidl
package com.zui.lib;
import com.zui.lib.data.Worker;   // 注意自定义的类一定要import,即使该类与此文件在同一个包同一级目录下也要导入

interface IMyAidlInterface {
  String getName();
  void setName(String name);        // aidl默认支持的数据类型定向tag必须是in,书写时可以省略
  void setWorker(in Worker worker);
  Worker getWorker(out Worker worker);
  Worker modifyWorker(inout Worker worker);
}

2、接下来需要书写服务端的java文件

首先是自定义的Worker数据类型Worker.java(注意需要Parcelable 接口)

package com.zui.lib.data;

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

public class Worker implements Parcelable {
    String mName;
    int mAge;
    String mJob;

    public Worker() {
    }

    public Worker(String mName, int mAge, String mJob) {
        this.mName = mName;
        this.mAge = mAge;
        this.mJob = mJob;
    }

    public Worker(Parcel source) {
        mName = source.readString();
        mAge = source.readInt();
        mJob = source.readString();
    }

    public String getName() {
        return mName;
    }

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

    public int getAge() {
        return mAge;
    }

    public void setAge(int mAge) {
        this.mAge = mAge;
    }

    public String getJob() {
        return mJob;
    }

    public void setJob(String mJob) {
        this.mJob = mJob;
    }

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mName);
        dest.writeInt(mAge);
        dest.writeString(mJob);
    }

    public void readFromParcel(Parcel in){
//        mName = in.readString();
//        mAge = in.readInt();
//        mJob = in.readString();
    }

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

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

    @Override
    public String toString() {
        return "Worker{" +
                "mName='" + mName + '\'' +
                ", mAge=" + mAge +
                ", mJob='" + mJob + '\'' +
                '}';
    }
}

注意Worker.aidl与worker.java包名目录层级要一致:例如本文com.zui.lib.data


然后创建一个MyService继承Service,在MyService中实现我们定义的IMyAidlInterface接口

package com.zui.aidltest;

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

import com.zui.lib.IMyAidlInterface;
import com.zui.lib.data.Worker;

public class MyService extends Service {
    String TAG = "AIDL MyService";
    public static Worker publicWorker = null;

    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new MyBinder();                  // 返回自定义的Binder对象吗(客户端绑定service的时候,服务端会将此对象提供给客户端,拿到此对象后客户端就可以享受服务端提供的服务了)
    }

    class MyBinder extends IMyAidlInterface.Stub{           // 实现IMyAidlInterface接口中的方法

        @Override
        public String getName() throws RemoteException {
            return "this is test name";
        }

        @Override
        public void setName(String name) throws RemoteException {
            publicWorker.setName(name);
        }

        @Override
        public void setWorker(Worker worker) throws RemoteException {
            publicWorker = worker;
            Log.d(TAG,"setWorker : worker = " + worker);
        }

        @Override
        public Worker getWorker(Worker worker) throws RemoteException {
            return publicWorker;

        }

        @Override
        public Worker modifyWorker(Worker worker) throws RemoteException {
            publicWorker = worker;
            return publicWorker;
        }
    }
}

至此,服务端就算编写完成了,下面介绍客户端app中的实现

二、客户端

1、客户端也需要重复定义服务端的aidl文件,注意客户端的aidl文件要与服务端保持完全一致,所以这里我就直接将服务端的的aidl文件夹拷贝到客户端,同时为了满足自定义的数据类型包名目录层级与aidl中定义的一致,同时将服务端的自定义数据类型java文件也拷贝到客户端,如下图


2、编写MainActivity绑定服务,与服务端进行通信

package com.zhf.aidlclient;

import android.content.ComponentName;
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 com.zui.lib.IMyAidlInterface;
import com.zui.lib.data.Worker;

public class MainActivity extends AppCompatActivity {
    String TAG = "AIDL MainActivity";
    private IMyAidlInterface mIMyAidlInterface;
    private MyServiceConnection mMyServiceConnection;
    Worker mWorker;
    private class MyServiceConnection implements ServiceConnection {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {           //绑定成功回调
            Log.d(TAG,"onServiceConnected");
            mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);     //获取服务端提供的接口
            try {
                Log.d(TAG,mIMyAidlInterface.getName());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mMyServiceConnection = new MyServiceConnection();
        ComponentName componentName = new ComponentName("com.zui.aidltest","com.zui.aidltest.MyService");  // 服务端app的service
        Intent intent = new Intent();
        intent.setComponent(componentName);
        intent.setAction("android_bind_service");
        boolean bind = bindService(intent,mMyServiceConnection,BIND_AUTO_CREATE);      //  绑定服务端的service
        Log.d(TAG,"bind = "+ bind);
    }

    public Worker getWorker(View view) throws RemoteException {
        Log.d(TAG,"getWorker");
        return mIMyAidlInterface.getWorker(new Worker("worker_1",0,"get"));         // 获取服务端的数据,与服务端通信
    };

    public void setWorker(View view) throws RemoteException {
        Log.d(TAG,"setWorker");
        mWorker = new Worker("worker_1",1,"set");
        mIMyAidlInterface.setWorker(mWorker);           // 与服务端通信
    };

    public Worker modifyWorker(View view) throws RemoteException {
        Log.d(TAG,"modifyWorker");
        mWorker = new Worker("worker_2",2,"modify");
        return mIMyAidlInterface.modifyWorker(mWorker);  // 与服务端通信
    };

    @Override
    protected void onDestroy() {
        unbindService(mMyServiceConnection);            // 记得解绑service,否则会引起泄漏
        super.onDestroy();
    }
}

到这客户端也编写完成了,接下来就是客户端利用服务端提供的接口与服务端进行通信了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值