插件进程死亡检测
来源:互联网 发布:订餐系统源码 编辑:程序博客网 时间:2024/05/11 05:46
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方法啥都没做,直接返回了。
- 插件进程死亡检测
- 异常死亡进程的自动复活
- 一个进程的诞生与死亡
- 异常死亡进程的自动复活
- VB 进程死亡的自动复活
- 一个进程的诞生与死亡
- 一个进程的诞生于死亡
- 一个进程的诞生与死亡
- 进程的诞生与死亡的整个过程
- Mac解决下eclipse进程死亡
- 进程检测
- 死亡
- 死亡
- 死亡
- 死亡
- 死亡
- 死亡
- 《深入浅出MFC》——一个进程的诞生与死亡
- Repair the Wall
- HDU 3549 Flow Problem(最大流入门)
- Bootstrap Table--onEditableSave
- uva 12504 Updating a Dictionary
- 拓展STAX
- 插件进程死亡检测
- 欢迎使用CSDN-markdown编辑器
- linux下mysql的root密码忘记解决方法
- 数据库sql互转(oracle转mysql为例子)
- C语言函数sscanf()的用法
- 第四章:注释
- if与switch
- 关于fork
- Linux学习笔记(二)