系统中有一个监听BOOT_COMPLETED广播的自启应用,概率性出现启动后被kill掉的现象。Log如下:
08-12 16:48:40.453 773 908 I ActivityManager: Process com.test.xxx (pid 2376) has died 08-12 16:48:40.453 773 908 D ActivityManager: SVC-handleAppDiedLocked: app = ProcessRecord{19911aa7 2376:com.test.xxx/u0a41}, app.pid = 2376 08-12 16:48:40.453 773 908 D ActivityManager: SVC-mBroadcastQueues: [email protected] 08-12 16:48:40.453 773 908 D ActivityManager: SVC-mBroadcastQueues: [email protected]
Log出处:
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread) { // First check if this ProcessRecord is actually active for the pid. synchronized (mPidsSelfLocked) { ProcessRecord curProc = mPidsSelfLocked.get(pid); if (curProc != app) { Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc); return; } } BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics(); synchronized (stats) { stats.noteProcessDiedLocked(app.info.uid, pid); } if (!app.killed) { Process.killProcessQuiet(pid); Process.killProcessGroup(app.uid, pid); app.killed = true; } // Clean up already done if the process has been re-started. if (app.pid == pid && app.thread != null && app.thread.asBinder() == thread.asBinder()) { boolean doLowMem = app.instrumentationClass == null; boolean doOomAdj = doLowMem; if (!app.killedByAm) { Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died"); mAllowLowerMemLevel = true; } else { // Note that we always want to do oom adj to update our state with the // new number of procs. mAllowLowerMemLevel = false; doLowMem = false; } EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); if (DEBUG_CLEANUP) Slog.v( TAG, "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder()); handleAppDiedLocked(app, false, true); if (doOomAdj) { updateOomAdjLocked(); } if (doLowMem) { doLowMemReportIfNeededLocked(app); } } else if (app.pid != pid) { // A new process has already been started. Slog.i(TAG, "Process " + app.processName + " (pid " + pid + ") has died and restarted (pid " + app.pid + ")."); EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName); } else if (DEBUG_PROCESSES) { Slog.d(TAG, "Received spurious death notification for thread " + thread.asBinder()); } }
可以看到app.killedByAm = false,也就是说不是ActivityManager主动kill该应用,而是LowMemory的原因(for RAM)。
ProcessRecord里属性:
private final BatteryStatsImpl mBatteryStats; // where to collect runtime statistics final ApplicationInfo info; // all about the first app in the process final boolean isolated; // true if this is a special isolated process final int uid; // uid of process; may be different from 'info' if isolated final int userId; // user of process. final String processName; // name of the process // List of packages running in the process final ArrayMap<String, ProcessStats.ProcessStateHolder> pkgList = new ArrayMap<String, ProcessStats.ProcessStateHolder>(); ArraySet<String> pkgDeps; // additional packages we have a dependency on IApplicationThread thread; // the actual proc... may be null only if // 'persistent' is true (in which case we // are in the process of launching the app) ProcessStats.ProcessState baseProcessTracker; BatteryStatsImpl.Uid.Proc curProcBatteryStats; int pid; // The process of this application; 0 if none int[] gids; // The gids this process was launched with String requiredAbi; // The ABI this process was launched with String instructionSet; // The instruction set this process was launched with boolean starting; // True if the process is being started long lastActivityTime; // For managing the LRU list long lastPssTime; // Last time we retrieved PSS data long nextPssTime; // Next time we want to request PSS data long lastStateTime; // Last time setProcState changed long initialIdlePss; // Initial memory pss of process for idle maintenance. long lastPss; // Last computed memory pss. long lastCachedPss; // Last computed pss when in cached state. int maxAdj; // Maximum OOM adjustment for this process int curRawAdj; // Current OOM unlimited adjustment for this process int setRawAdj; // Last set OOM unlimited adjustment for this process int curAdj; // Current OOM adjustment for this process int setAdj; // Last set OOM adjustment for this process int curSchedGroup; // Currently desired scheduling class int setSchedGroup; // Last set to background scheduling class int trimMemoryLevel; // Last selected memory trimming level int curProcState = -1; // Currently computed process state: ActivityManager.PROCESS_STATE_* int repProcState = -1; // Last reported process state int setProcState = -1; // Last set process state in process tracker int pssProcState = -1; // The proc state we are currently requesting pss for boolean serviceb; // Process currently is on the service B list boolean serviceHighRam; // We are forcing to service B list due to its RAM use boolean setIsForeground; // Running foreground UI when last set? boolean notCachedSinceIdle; // Has this process not been in a cached state since last idle? boolean hasClientActivities; // Are there any client services with activities? boolean hasStartedServices; // Are there any started services running in this process? boolean foregroundServices; // Running any services that are foreground? boolean foregroundActivities; // Running any activities that are foreground? boolean repForegroundActivities; // Last reported foreground activities. boolean systemNoUi; // This is a system process, but not currently showing UI. boolean hasShownUi; // Has UI been shown in this process since it was started? boolean pendingUiClean; // Want to clean up resources from showing UI? boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower boolean treatLikeActivity; // Bound using BIND_TREAT_LIKE_ACTIVITY boolean bad; // True if disabled in the bad process list boolean killedByAm; // True when proc has been killed by activity manager, not for RAM boolean killed; // True once we know the process has been killed boolean procStateChanged; // Keep track of whether we changed 'setAdj'. String waitingToKill; // Process is waiting to be killed when in the bg, and reason IBinder forcingToForeground;// Token that is forcing this process to be foreground int adjSeq; // Sequence id for identifying oom_adj assignment cycles int lruSeq; // Sequence id for identifying LRU update cycles CompatibilityInfo compat; // last used compatibility mode IBinder.DeathRecipient deathRecipient; // Who is watching for the death. ComponentName instrumentationClass;// class installed to instrument app ApplicationInfo instrumentationInfo; // the application being instrumented String instrumentationProfileFile; // where to save profiling IInstrumentationWatcher instrumentationWatcher; // who is waiting IUiAutomationConnection instrumentationUiAutomationConnection; // Connection to use the UI introspection APIs. Bundle instrumentationArguments;// as given to us ComponentName instrumentationResultClass;// copy of instrumentationClass boolean usingWrapper; // Set to true when process was launched with a wrapper attached BroadcastRecord curReceiver;// receiver currently running in the app long lastWakeTime; // How long proc held wake lock at last check long lastCpuTime; // How long proc has run CPU at last check long curCpuTime; // How long proc has run CPU most recently long lastRequestedGc; // When we last asked the app to do a gc long lastLowMemory; // When we last told the app that memory is low boolean reportLowMemory; // Set to true when waiting to report low mem boolean empty; // Is this an empty background process? boolean cached; // Is this a cached process? String adjType; // Debugging: primary thing impacting oom_adj. int adjTypeCode; // Debugging: adj code to report to app. Object adjSource; // Debugging: option dependent object. int adjSourceProcState; // Debugging: proc state of adjSource's process. Object adjTarget; // Debugging: target component impacting oom_adj. Runnable crashHandler; // Optional local handler to be invoked in the process crash.
过滤掉特定应用:
if (!app.killed) { Process.killProcessQuiet(pid); Process.killProcessGroup(app.uid, pid); app.killed = true; }
修改为:
if (!app.killed) { if(!"com.test.xxx".equals(app.processName)){ Process.killProcessQuiet(pid); Process.killProcessGroup(app.uid, pid); } app.killed = true; }
原文:http://blog.csdn.net/zhoumushui https://blog.csdn.net/zhoumushui/article/details/52239884