您的位置:首页 > 移动开发 > Android开发

插件进程死亡检测

2017-08-02 18:43 204 查看

3插件进程死亡检测

插件进程死亡时,宿主是如何知道的呢?通过RemoteCallbackList机制。

还有万一宿主挂掉了呢,插件进程是如何知道的?

插件进程启动的时候,创建宿主Application并调用其onCreate(),因此会调用到PluginHelper的applicationOnCreate()方法。

前面论述过,除了进行Hook 初始化之外,还进行了启动并绑定PluginManagerService服务。再说一次, PluginManager是运行于

插件中的客户端,而IpluginManagerImpl是运行于宿主的服务端。

PluginManager的onServiceConnected方法完成了2件事情,

1,调用服务端的registerApplicationCallback方法进行注册。

mPluginManager.registerApplicationCallback(new IApplicationCallback.Stub() {
@Override
public Bundle onCallback(Bundle extra) throws RemoteException {
return extra;
}
});


2,监听服务端是否死亡。

mPluginManager.asBinder().linkToDeath(new IBinder.DeathRecipient() {
@Override
public void binderDied() {
onServiceDisconnected(componentName);
}
}, 0);

服务端IpluginManagerImpl如果死亡,就会调用onServiceDisconnected方法,

public void onServiceDisconnected(ComponentName componentName) {
Log.i(TAG, "onServiceDisconnected disconnected!");
mPluginManager = null;

Iterator<WeakReference<ServiceConnection>> iterator = sServiceConnection.iterator();
while (iterator.hasNext()) {
WeakReference<ServiceConnection> wsc = iterator.next();
ServiceConnection sc = wsc != null ? wsc.get() : null;
if (sc != null) {
sc.onServiceDisconnected(componentName);
} else {
iterator.remove();
}
}
//服务连接断开,需要重新连接。
connectToService();
}

onServiceDisconnected方法也很简单,直接重新启动绑定服务端。

回头看看registerApplicationCallback方法, IpluginManagerImpl的registerApplicationCallback方法如下,

public boolean registerApplicationCallback(IApplicationCallback callback) throws RemoteException {
return mActivityManagerService.registerApplicationCallback(Binder.getCallingPid(), Binder.getCallingUid(), callback);
}

BaseActivityManagerService的registerApplicationCallback方法如下,

public boolean registerApplicationCallback(int callingPid, int callingUid, IApplicationCallback callback) {
return mRemoteCallbackList.register(callback, new ProcessCookie(callingPid, callingUid));
}

ProcessCookie是内部类,主要保存插件进程的pid,uid信息。

mRemoteCallbackList是内部类MyRemoteCallbackList对象,

private RemoteCallbackList<IApplicationCallback> mRemoteCallbackList;

在BaseActivityManagerService的构造方法中,

public void onCreate(IPluginManagerImpl pluginManagerImpl) throws Exception {
if (mRemoteCallbackList == null) {
mRemoteCallbackList = new MyRemoteCallbackList();
}
}


MyRemoteCallbackList定义如下,

private class MyRemoteCallbackList extends RemoteCallbackList<IApplicationCallback> {
@Override
public void onCallbackDied(IApplicationCallback callback, Object cookie) {
super.onCallbackDied(callback, cookie);
if (cookie != null && cookie instanceof ProcessCookie) {
ProcessCookie p = (ProcessCookie) cookie;
onProcessDied(p.pid, p.uid);
}
}
}

继承于RemoteCallbackList,实现了onCallbackDied方法。

因此,当插件进程die的时候,就会调用onCallbackDied方法,这样就可以达到监听插件的目的。

onProcessDied方法如下,

protected void onProcessDied(int pid, int uid) {
Log.i(TAG, "onProcessDied,pid=%s,uid=%s", pid, uid);
}

这个方法其实啥都没做。

另外,注册的目的其实是监听,并不是为了服务端回调onCallback方法。

虽然有一个sendCallBack方法里调用客户端的onCallback方法,

protected void sendCallBack(Bundle extra) {
if (mRemoteCallbackList != null) {
int i = mRemoteCallbackList.beginBroadcast();
while (i > 0) {
i--;
try {
mRemoteCallbackList.getBroadcastItem(i).onCallback(extra);
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mRemoteCallbackList.finishBroadcast();
}
}

但是这个方法从来都不会调用,并且客户端PluginManager的onCallback方法啥都没做,直接返回了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android DroidPlugin