AIdl server端监听client是否掉线

我们知道当绑定service时 客户端可以收到服务端异常中断的消息 即onServiceConnected,那么服务器端是否可以监听到client端掉线的消息呢?下面就写个简单的demo用于监听client是否掉线
分三个moudle 分别是client server和AIDL模块 AIDL模块专门放AIDL文件 client server分别依赖AIDL模块

AIDL模块:

IClientCallback

// IClientCallback.aidl
package com.example.commonlib;

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

interface IClientCallback {
    void clientDiedCallBack();
}

IAIDLInterface

// IAIDLInterface.aidl
package com.example.commonlib;
import com.example.commonlib.IClientCallback;

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

interface IAIDLInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    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 否则Android studio无法识别这些AIDL

Server端

package com.example.myapplication.server;

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

import androidx.annotation.Nullable;

import com.example.commonlib.IAIDLInterface;
import com.example.commonlib.IClientCallback;

import java.util.Locale;


/**
 * Created by hjcai on 2021/3/29.
 */
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="com.example.myapplication.server.ServiceInServer">
            <intent-filter>
                <action android:name="aaa.aaa" />
            </intent-filter>
        </service>

Client端

ClientCallBack用于注册到Server端

package com.example.aidlclient;

import android.os.RemoteException;

import com.example.commonlib.IClientCallback;

/**
 * Created by hjcai on 2021/3/29.
 */
public class ClientCallBack extends IClientCallback.Stub{
    @Override
    public void clientDiedCallBack() throws RemoteException {

    }
}

ClientServiceConnection

package com.example.aidlclient;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.example.commonlib.IAIDLInterface;

import java.util.List;


/**
 * Created by hjcai on 2021/3/29.
 */
class ClientServiceConnection implements ServiceConnection {
    private final static ClientServiceConnection INSTANCE = new ClientServiceConnection();

    private static final String SERVICE_INTENT = "aaa.aaa";
    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("ACCAaaaa");
            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(View view) {
        ClientServiceConnection.getInstance().bindService(this);
    }

调用顺序
在这里插入图片描述

在第三步之后 可以拿到远端服务端的代理 间接调用远端的接口 在第五步之后 如果杀掉client端 会触发服务器端RemoteCallbackList<IClientCallback> callbackList的onCallbackDied 达到监听client端的作用
在这里插入图片描述

升级:辨认是哪个client掉线

我们可以通过修改AIDL的接口 来达到这个目的
1.修改接口IAIDLInterface:

void registerClientCallback(IClientCallback callBack,String cookie);//增加一个参数

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("ACCAaaaa");
            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 cookie) throws RemoteException {
            Log.e(TAG, "registerClientCallback: "+cookie);
            callbackList.register(callBack,cookie);//主要是这里
        }
    };

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

        callbackList = new RemoteCallbackList<IClientCallback>() {

            @Override
            public void onCallbackDied(IClientCallback callback, Object cookie) {
                super.onCallbackDied(callback, cookie);
                // 可以通过cookie判断是哪个client掉线了
                Log.e(TAG, "onCallbackDied: "+callback+" cookie "+cookie);
                try {
                    callback.clientDiedCallBack();
                } catch (RemoteException e) {
                    Log.e(TAG, "onCallbackDied: "+e);
                    e.printStackTrace();
                }
            }
        };
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值