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();
}