AIdl server端监听client是否被kill掉断开连接,

client可以通过onServiceConnected来监听server是否连接中断, server怎么监听client是否连接中断呢?

如下,上代码。

AIDL

IClientCallback.aidl

interface IClientCallback {
    void clientDiedCallBack();
}

IAIDLInterface.aidl

interface IAIDLInterface {
    
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);

    String getString(String s);

    int getInt(int i);

    void registerClientCallback(IClientCallback callBack);
}

rebuild 查看AIDL是否编译成功。

Server端

public class ServiceInServer extends Service {
    RemoteCallbackList<IClientCallback> callbackList;

    private static final String TAG = "ServiceInServer";

    @Override
    public void onCreate() {
        super.onCreate();
        callbackList = new RemoteCallbackList() {
            @Override
            public void onCallbackDied(IInterface callback) {
                Log.e(TAG, "onCallbackDied: ");
            }
        };
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind: ");
        return mBinder;
    }

    private final IAIDLInterface.Stub mBinder = new IAIDLInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public String getString(String s) throws RemoteException {
            return castClientStringToServer(s);
        }

        @Override
        public int getInt(int i) throws RemoteException {
            return 0;
        }

        @Override
        public void registerClientCallback(IClientCallback callBack) throws RemoteException {
            Log.e(TAG, "registerClientCallback: ");
            callbackList.register(callBack);
        }
    };

    protected String castClientStringToServer(String s) {
        Log.e(TAG, "castClientStringToServer: " + s);
        return s.toUpperCase(Locale.US);
    }
}

清单文件注册service

<service android:name=".server.ServiceInServer">
            <intent-filter>
                <action android:name="client" />
            </intent-filter>
</service>

Client端

ClientCallBack用来注册到Server端的

public class ClientCallBack extends IClientCallback.Stub{
    @Override
    public void clientDiedCallBack() throws RemoteException {

    }
}

ClientServiceConnection

class ClientServiceConnection implements ServiceConnection {
    private final static ClientServiceConnection INSTANCE = new ClientServiceConnection();

    private static final String SERVICE_INTENT = "client";
    private static final String TAG = "Client";
    IAIDLInterface mServer = null;

    private ClientServiceConnection() {
    }

    public static ClientServiceConnection getInstance() {
        return INSTANCE;
    }

    public void bindService(Context context) {
        Log.e(TAG, "bindService: ");
        if (null == context) return;
        try {
            Intent intent = new Intent();
            intent.setAction(SERVICE_INTENT);
            Intent explicitIntent = getExplicitIntent(intent, context);
            context.bindService(explicitIntent, this, Service.BIND_AUTO_CREATE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Intent getExplicitIntent(Intent implicitIntent, Context context) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String className = serviceInfo.serviceInfo.name;
        Log.e(TAG, "service package=" + serviceInfo.serviceInfo.packageName);
        ComponentName component = new ComponentName(serviceInfo.serviceInfo.packageName, className);

        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);
        return explicitIntent;
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.e(TAG, "onServiceConnected: ");
        synchronized (this) {
            this.mServer = IAIDLInterface.Stub.asInterface(service);

            try {
                Log.e(TAG, "registerClientCallback: ");
                this.mServer.registerClientCallback(new ClientCallBack());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        try {
            String s = mServer.getString("client1");
            Log.e(TAG, "onServiceConnected: " + s);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.e(TAG, "onServiceDisconnected: ");
    }

    @Override
    public void onBindingDied(ComponentName name) {

    }

    @Override
    public void onNullBinding(ComponentName name) {

    }
}

写个button调用如下方法

public void bind(Context context) {
        ClientServiceConnection.getInstance().bindService(context);
    }

调用顺序

1、Client  bindService。

2、Server  onBind(Callback)

3、onServiceConnected(Callback)

4、registerClientCallback()

5、registerClientCallback(Callback)

在第3步之后 可以拿到远端服务端的代理 间接调用远端的接口 在第5步之后 如果杀掉client端 会触发服务器端RemoteCallbackList<IClientCallback> callbackList的onCallbackDied 达到监听client端的作用

升级:如果有多个client bindServer 判断是哪个client断开连接了

通过修改AIDL的接口 来判断是哪个client断开连接了
1.修改接口IAIDLInterface:

//增加一个参数key,来区分是哪一个client
void registerClientCallback(IClientCallback callBack,String key);

2.修改client的注册代码

@Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.e(TAG, "onServiceConnected: ");
        synchronized (this) {
            this.mServer = IAIDLInterface.Stub.asInterface(service);

            try {
                Log.e(TAG, "registerClientCallback: ");
                this.mServer.registerClientCallback(new ClientCallBack(),this.getClass().getName());//关键部分
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        try {
            String s = mServer.getString("client1");
            Log.e(TAG, "onServiceConnected: " + s);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

3.修改service端的实现

private final IAIDLInterface.Stub mBinder = new IAIDLInterface.Stub() {
        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public String getString(String s) throws RemoteException {
            return castClientStringToServer(s);
        }

        @Override
        public int getInt(int i) throws RemoteException {
            return 0;
        }

        @Override
        public void registerClientCallback(IClientCallback callBack, String key) throws RemoteException {
            Log.e(TAG, "registerClientCallback: "+key);
            // 关键代码
            callbackList.register(callBack,cookie);
        }
    };

4.修改回调 使用带key的回调

callbackList = new RemoteCallbackList<IClientCallback>() {

            @Override
            public void onCallbackDied(IClientCallback callback, Object key) {
                super.onCallbackDied(callback, key);
                // 可以通过key判断是哪个client掉线了
                Log.e(TAG, "onCallbackDied: "+callback+" key " + key);
                try {
                    callback.clientDiedCallBack();
                } catch (RemoteException e) {
                    Log.e(TAG, "onCallbackDied: "+e);
                    e.printStackTrace();
                }
            }
        };

补充:

也可以在Server端的registerClientCallback里添加死亡代理,也能监听到client断开连接。

   sceneAPI = IModeAPI.Stub.asInterface(iBinder);
try {
                sceneAPI.asBinder().linkToDeath(deathRecipient, 0);
            } catch (RemoteException e) {
                e.printStackTrace();
}

要让Java客户端调用C++实现的AIDL服务,需要使用JNI(Java Native Interface)。以下是实现步骤: 1.编写本地服务代码:使用C++编写本地服务的代码,并将其编译成本地库,例如.dll文件(Windows平台)或.so文件(Linux平台)。 2.编写AIDL接口:在Android中,使用AIDL定义接口。你需要编写一个AIDL文件来定义服务的接口。 3.编写Java代码:在Java中编写客户端代码,并使用JNI调用本地库。你需要将AIDL接口转换为Java接口,并使用JNI调用本地实现。 4.将本地库加载到Java中:使用System.loadLibrary()方法将本地库加载到Java中。 5.连接到服务:在Java代码中连接到AIDL服务。 以下是一个简单的示例代码: C++本地服务代码: ```cpp #include <jni.h> JNIEXPORT jstring JNICALL Java_com_example_MyService_nativeMethod(JNIEnv *env, jobject obj) { return env->NewStringUTF("Hello from native method!"); } ``` AIDL接口: ```aidl interface IMyService { String sayHello(); } ``` Java客户端代码: ```java public class MyService extends Service { // 声明本地方法 private native String nativeMethod(); // 实现AIDL接口 private final IMyService.Stub mBinder = new IMyService.Stub() { @Override public String sayHello() throws RemoteException { return nativeMethod(); // 调用本地方法 } }; @Override public IBinder onBind(Intent intent) { return mBinder; // 返回AIDL接口 } static { System.loadLibrary("mylib"); // 加载本地库 } } ``` 注意:这只是一个简单的示例,实际情况可能更加复杂。你需要仔细阅读JNI和AIDL文档,并且确保你的本地代码和Java代码之间的交互是正确的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yayayaiii

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值