This can be done by the Binder.linkToDeath()
mechanism - You'll have to ask each client to send new Binder()
object that they initiated and then link to their (your clients') death.
I'll explain how to preform this using AIDL files.
(You can choose any android IPC mechanism as long as you can pass Binder objects from your client's to your service)
Code Example -
Inside your .AIDL
file - Create a method to pass the IBinder
object from the client to the service
void registerProcessDeath(in IBinder clientDeathListener, String packageName);
On the client side - Initialize a new object and pass it to your service via AIDL interface.
public void onServiceConnected(ComponentName className, IBinder service) {
mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
mIMyAidlInterface.registerProcessDeath(new Binder(),getPackageName());
}
On the service side -
1. Get the client's Binder
and register to his linkToDeath()
.
2. Use helper class to handle all clients via android's IBinder.DeathRecipient class
public class MyService extends Service {
private volatile ClientsDeathWatcher mClientsList;
@Override
public IBinder onBind(Intent intent) {
mClientsList = new ClientsDeathWatcher();
return mStub;
}
private final IMyAidlInterface.Stub mStub = new IMyAidlInterface.Stub() {
@Override
public void registerProcessDeath(IBinder cb, String packageName){
boolean isRegistered = mClientsList.register(cb , packageName);
}
};
}
public class ClientsDeathWatcher {
private ArrayMap<String, DeathCallBack> mCallbacks = new ArrayMap<>();
private final class DeathCallBack implements IBinder.DeathRecipient {
private String pn;
private IBinder mBinder;
DeathCallBack(String packageName,IBinder binder) {
pn = packageName;
mBinder = binder;
}
public void binderDied() {
synchronized (mCallbacks) {
mBinder.unlinkToDeath(this,0);
clientDeath(pn);
}
}
}
private void clientDeath(String packageName) {
mCallbacks.remove(packageName);
}
public boolean register(IBinder token, String packageName) {
synchronized (mCallbacks) {
try {
if (!mCallbacks.containsKey(packageName)) {
DeathCallBack mDeathCallBack = new DeathCallBack(packageName,token);
mCallbacks.put(packageName, mDeathCallBack);
token.linkToDeath(mDeathCallBack, 0);
}
return true;
} catch (RemoteException e) {
e.printStackTrace();
return false;
}
}
}
}
onUnbind
在Android框架中深入处理,我不确定在远程进程情况下是否保证调用它。 - zapl