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

在这里插入图片描述

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

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

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

一、服务端

结构如下
在这里插入图片描述

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

<service
            android:name=".MyAidlService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="${applicationId}.IMyAidlInterface" />
            </intent-filter>
        </service>
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<AidlBean> CREATOR = new Creator<AidlBean>() {
        @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 + '\'' +
                '}';
    }
}

二、客户端

结构如下
在这里插入图片描述

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();
            }
        });
    }
}
  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要为 Android AIDL 服务添加回调,您可以执行以下步骤: 1.在 AIDL 接口中定义回调方法。 2.创建一个接受回调的接口。 3.在服务中实现回调接口,并在需要时调用该接口的方法。 4.在客户端中实现回调接口,并将其传递给服务。 以下是一个简单的示例: 服务端代码: ```aidl interface IMyServiceCallback { void onUpdate(int progress); } interface IMyService { void startTask(); void registerCallback(IMyServiceCallback callback); } class MyService extends Service { private IMyServiceCallback mCallback; private final IMyService.Stub mBinder = new IMyService.Stub() { @Override public void startTask() throws RemoteException { // 启动耗时任务 for (int i = 0; i <= 100; i++) { if (mCallback != null) { mCallback.onUpdate(i); } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } } @Override public void registerCallback(IMyServiceCallback callback) throws RemoteException { mCallback = callback; } }; @Nullable @Override public IBinder onBind(Intent intent) { return mBinder; } } ``` 客户端代码: ```aidl class MyServiceConnection implements ServiceConnection { private IMyService mService; private final IMyServiceCallback.Stub mCallback = new IMyServiceCallback.Stub() { @Override public void onUpdate(int progress) throws RemoteException { // 更新进度条 } }; @Override public void onServiceConnected(ComponentName componentName, IBinder iBinder) { mService = IMyService.Stub.asInterface(iBinder); try { // 注册回调 mService.registerCallback(mCallback); // 启动任务 mService.startTask(); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName componentName) { mService = null; } } ``` 在这个示例中,服务端定义了一个回调接口 `IMyServiceCallback`,并在 AIDL 接口 `IMyService` 中添加了 `registerCallback()` 方法,用于向服务注册回调。服务端实现了 `registerCallback()` 方法,并在任务执行过程中调用回调接口的 `onUpdate()` 方法通知客户端。客户端实现了回调接口 `IMyServiceCallback`,并将其传递给服务端,在任务执行期间,服务端会调用客户端的 `onUpdate()` 方法通知客户端任务进度的更新。 希望这可以帮助您为 Android AIDL 服务添加回调。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值