插件进程死亡检测
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方法啥都没做,直接返回了。
相关文章推荐
- Shell脚本实现检测进程是否正在运行
- 写一个检测网线是否被拔出的守护进程(嵌入式设备上)
- WINCE 检测 进程是否运行
- js浏览器和浏览器插件检测的方法总结
- Valgrind原理和检测S++插件内存泄漏的实例方法
- 检测锁死进程的ID
- JS插件检测
- Android中startActivity中的permission检测与UID机制 共享进程
- Icesword的进程检测分析
- windows 下检测进程cpu使用率
- 内核级利用通用Hook函数方法检测进程
- 检测浏览器安装的插件
- iDempiere 开发指南 Process(iDem后台进程)及插件的开发及部署
- VB-检测指定的进程是否存在
- 基于nagios的监控环境(四):第三方插件监控流量、CPU、内存、进程
- php中一个检测内存使用情况的pecl插件
- 直插件焊点检测算法的初步规划(未成形呢)
- IBM的LPI复习资料之LPI101-Topic103 :GNU和Unix命令(5)创建、检测、结束进程
- 检测IE8及以下的浏览器并安装chrome frame插件
- maven 使用 checkstyle findbugs pmd 代码覆盖率检测等插件的使用