Android AIDL使用(双向callback,传递自定义类型)

Android AIDL使用(双向callback,传递自定义类型)_第1张图片

适用于单服务端多客户端及1:N

1.可以将多个客户端同时连接到某项服务。但是,系统会缓存 IBinder 服务通信通道。换言之,只有在第一个客户端绑定服务时,系统才会调用服务的 onBind() 方法来生成 IBinder。然后,系统会将该 IBinder 传递至绑定到同一服务的所有其他客户端,无需再次调用 onBind()。
2.当最后一个客户端取消与服务的绑定时,服务端会执行onUnbind,系统会销毁该服务.

注:纯AIDL 接口可能同时向服务发送多个请求,那么服务就必须执行多线程处理。

一、服务端

结构如下
Android AIDL使用(双向callback,传递自定义类型)_第2张图片

1.aidl文件如下
// AidlBean.aidl
package com.example.aidlservice;

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

parcelable AidlBean;
// ICallback.aidl
package com.example.aidlservice;
import com.example.aidlservice.AidlBean;

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

interface ICallback {//服务端反馈给客户端
    void onResponseSuccess(String tag,String data,in AidlBean bean);

    void onResponseErr(int type,String errMsg);
}
// IMyAidlInterface.aidl
package com.example.aidlservice;
import com.example.aidlservice.ICallback;

interface IMyAidlInterface {//提供客户端调用接口
    /**
     * input surface,surfaceWidth,surfaceHeight
     */
    void setSurface(in Surface surface,in int width,in int height);
    /**
     * on client surface ondestroy
     */
    void onSurfaceDestroy();
    /**
     * service use callback notify client
     */
    void registerCallback(in ICallback callback,in String tag);

    void unRegisterCallback(in ICallback callback,in String tag);

    void getDataList(in String tag);

    /**
     * client use callback notify service
     * it can work,but it has no value
     */
    ICallback getCallback();
}
2.服务类(MyAidlService)

AndroidManifest.xml


            
                
            
        
package com.example.aidlservice;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.view.Surface;

import androidx.annotation.Nullable;

import com.example.aidlservice.util.L;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * @author Liushihua
 * @date 2022-5-10 14:39
 * @desc
 */
public class MyAidlService extends Service {
    private ICallback callback;
    private Handler handler = new Handler(Looper.myLooper());

    private ICallback.Stub mCallback = new ICallback.Stub() {

        @Override
        public void onResponseSuccess(String tag, String data, AidlBean bean) throws RemoteException {
            L.d("onResponseSuccess:" + data + "   " + bean);
        }

        @Override
        public void onResponseErr(int type, String errMsg) throws RemoteException {

        }
    };

    private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
        @Override
        public void setSurface(Surface surface, int width, int height) throws RemoteException {
            L.d("setSurface width:" + width + "  thread:" + Thread.currentThread().getId() + "  binder:" + binder);
        }

        @Override
        public void onSurfaceDestroy() throws RemoteException {
            L.d("onSurfaceDestroy");
        }

        @Override
        public void registerCallback(ICallback callback, String tag) throws RemoteException {
            L.d("registerCallback:" + tag);
            MyAidlService.this.callback = callback;
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    try {
                        callback.onResponseSuccess(tag, "服务端延时反馈消息", new AidlBean("服务", "000", 0));
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }, 3000);
        }

        @Override
        public void unRegisterCallback(ICallback callback, final String tag) throws RemoteException {
            L.d("unRegisterCallback:" + tag);
            MyAidlService.this.callback = null;
        }

        @Override
        public void getDataList(final String tag) throws RemoteException {
            try {
                JSONObject object = new JSONObject();
                for (int i = 1; i < 11; i++) {
                    object.put("key" + i, i);
                }
                callback.onResponseSuccess(tag, object.toString(), new AidlBean("服务getDataList", "000", 0));
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public ICallback getCallback() throws RemoteException {
            return mCallback;
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        L.d("onBind:" + binder);
        return binder;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        L.d("onUnbind:" + Thread.currentThread().getId());
        return super.onUnbind(intent);
    }

    @Override
    public void onDestroy() {
        L.d("onDestroy:" + Thread.currentThread().getId());
        callback = null;
        binder = null;
        super.onDestroy();
    }
}

3.传递自定义类型
package com.example.aidlservice;

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

/**
 * @author Liushihua
 * @date 2022-5-11 13:44
 * @desc
 */
public class AidlBean implements Parcelable {
    private String name;
    private int age;
    private String id;

    public AidlBean(Parcel in) {
        name = in.readString();
        age = in.readInt();
        id = in.readString();
    }

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

    public static final Creator CREATOR = new Creator() {
        @Override
        public AidlBean createFromParcel(Parcel in) {
            return new AidlBean(in);
        }

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

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

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeInt(age);
        dest.writeString(id);
    }

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

二、客户端

结构如下
Android AIDL使用(双向callback,传递自定义类型)_第3张图片

package com.example.aidlclient;

import androidx.appcompat.app.AppCompatActivity;

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 com.example.aidlservice.AidlBean;
import com.example.aidlservice.ICallback;
import com.example.aidlservice.IMyAidlInterface;

public class MainActivity extends AppCompatActivity {
    private IMyAidlInterface anInterface;
    private ICallback callService;

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

    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            L.d("connection onServiceConnected");
            anInterface = IMyAidlInterface.Stub.asInterface(service);

            try {
                callService = anInterface.getCallback();
                anInterface.setSurface(null, 333, 333);
                callService.onResponseSuccess("来自客户端", "来自客户端", new AidlBean("客户端", "111", 1));
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            L.d("connection onServiceDisconnected");
        }
    };

    private ICallback.Stub callback = new ICallback.Stub() {
        @Override
        public void onResponseSuccess(String tag, String data, AidlBean bean) throws RemoteException {
            L.d("333  onResponseSuccess:" + data + "  " + bean);

        }

        @Override
        public void onResponseErr(int type, String errMsg) throws RemoteException {
            L.d("333  onResponseErr:" + errMsg);
        }
    };

    private void initView() {
        findViewById(R.id.btn).setOnClickListener(v -> {
            Intent intent = new Intent(IMyAidlInterface.class.getName());
            intent.setPackage(IMyAidlInterface.class.getPackage().getName());
            bindService(intent, connection, Context.BIND_AUTO_CREATE);
        });
        findViewById(R.id.btn_1).setOnClickListener(v -> {
            try {
                unbindService(connection);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        findViewById(R.id.btn_2).setOnClickListener(v -> {
            try {
                anInterface.registerCallback(callback, "333");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        });
        findViewById(R.id.btn_3).setOnClickListener(v -> {
            try {
                anInterface.getDataList("TAG_333");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        });
    }
}

你可能感兴趣的:(Android基础,android,aidl)