Android Framework 使用AMS实时监控应用进程死亡
修改文件:
ActivityManagerService.java
APK
原理:
原生代码中会在每个应用进程启动时,创建一个AppDeathRecipient对象来监控其是否death,进程挂掉(包括走onDestroy的、或者crash)后,执行回调方法处理此应用的各组件资源的后续。利用此点,我们定义一个自己的XXXXCallerDeathRecipient类,并在其回调中写我们要在进程挂掉时需要同时做的事。
功能代码需要写在AMS所在的包中,要从AMS的包内变量mPidsSelfLocked获取相关应用进程。
应用端通过获取ams服务(详见我另一篇 访问系统隐藏类 的随笔),调用 watchXXXXDeathforProcess 并传入应用pid即可。
代码例如:
apk侧:
int pid = android.os.Process.myPid(); Log.v("XXXX", "myPID: " + pid); Method method = null; try { method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class); IBinder binder = (IBinder) method.invoke(null, Context.ACTIVITY_SERVICE); IActivityManager mIPm = IActivityManager.Stub.asInterface(binder); mIPm.watchXXXXDeathforProcess(pid); } catch (NoSuchMethodException | ClassNotFoundException | InvocationTargetException | IllegalAccessException | RemoteException e) { Log.e("XXXX", "XXXX catch Exception: " + e); e.printStackTrace(); }
Framework侧:
ActivityManagerService.XXXXCallerDeathRecipient adr; private final class XXXXCallerDeathRecipient implements IBinder.DeathRecipient { final ProcessRecord mApp; final int mPid; final IApplicationThread mAppThread; XXXXCallerDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread) { if (DEBUG_ALL) Slog.v( TAG, "XXXX death recipient " + this + " for thread " + thread.asBinder()); mApp = app; mPid = pid; mAppThread = thread; } @Override public void binderDied() { Slog.v(TAG, "XXXX Death received in " + this + " for thread " + mAppThread.asBinder() + " mPid is " + mPid); try { // your code } catch (RemoteException e) { Slog.e(TAG, "XXXX restoreAllDirOwner has RemoteException when binderDied: " + e); } mApp.getThread().asBinder().unlinkToDeath(adr, 0); } } public boolean watchXXXXDeathforProcess(int pid) { ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } Slog.d(TAG, "XXXX watchDeathforProcess for: " + app.processName + " pid: " + app.mPid); try { adr = new ActivityManagerService.XXXXCallerDeathRecipient( app, pid, app.getThread()); app.getThread().asBinder().linkToDeath(adr, 0); app.setDeathRecipient(adr); return true; } catch (RemoteException e) { Slog.e(TAG, "XXXX watchDeathforProcess has RemoteException: " + e); } } return false; }
本文来自博客园,作者:小汀,转载请注明原文链接:https://www.cnblogs.com/1118zjg/p/17172017.html