Android 常驻进程如何被查杀?

一、常驻进程的特点

1. 常驻进程的类型
2. 常驻进程的特性
复制代码
常驻进程通常具有以下特点:
    1. 使用 START_STICKY 返回值
    2. 可能是前台服务(有通知)
    3. 绑定到系统进程
    4. 使用 WakeLock 保持唤醒

二、降低常驻进程优先级的方法

方法一:停止前台服务

如果常驻进程运行着前台服务,停止它可以显著降低优先级:

复制代码
public class MyDaemonService extends Service {
    
    private static final int NOTIFICATION_ID = 10001;
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 启动前台服务(高优先级)
        startForeground(NOTIFICATION_ID, createNotification());
        
        // 运行一段时间后,停止前台服务(降低优先级)
        scheduleStopForeground();
        
        return START_STICKY;
    }
    
    private void scheduleStopForeground() {
        new Handler(Looper.getMainLooper()).postDelayed(() -> {
            // 停止前台服务,转为后台服务
            stopForeground(true);
        }, 30 * 1000); // 30秒后停止
    }
    
    private Notification createNotification() {
        return new Notification.Builder(this, "channel")
            .setContentTitle("Daemon Running")
            .setSmallIcon(R.drawable.ic_launcher)
            .build();
    }
}
方法二:调整进程状态
复制代码
public void lowerDaemonPriority() {
    // 1. 设置线程优先级为后台
    android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);
    
    // 2. 设置进程组为后台组
    try {
        android.os.Process.setProcessGroup(
            android.os.Process.myPid(),
            android.os.Process.THREAD_GROUP_BACKGROUND
        );
    } catch (Exception e) {
        e.printStackTrace();
    }
    
    // 3. 如果有 WakeLock,释放它
    if (mWakeLock != null && mWakeLock.isHeld()) {
        mWakeLock.release();
    }
}
方法三:解绑系统进程
复制代码
public void unbindFromSystemService() {
    // 解绑之前绑定的系统服务
    if (mSystemServiceConnection != null) {
        unbindService(mSystemServiceConnection);
        mSystemServiceConnection = null;
    }
}

三、特殊情况:系统级常驻进程

1. 系统服务的保护机制

系统级常驻进程(如 AMS、WMS、SystemUI)有特殊保护:

复制代码
// 系统服务的优先级设置
// frameworks/base/services/core/java/com/android/server/am/ProcessList.java

// 系统进程的 OOM_ADJ 值(非常低,不容易被杀)
static final int SYSTEM_ADJ = -16;
static final int SYSTEM_SERVER_ADJ = -12;
2. SELinux 限制

系统级进程受到 SELinux 策略的保护:

复制代码
SELinux 策略会阻止普通应用:
    - 修改系统进程的优先级
    - 向系统进程发送信号
    - 读取系统进程的内存
3. Root 权限的影响

如果有 Root 权限,可以绕过一些限制:

复制代码
# 通过 adb 降低进程优先级(需要 Root)
adb shell renice 19 -p <pid>

# 或使用 setprop 命令
adb shell setprop sys.powerctl reboot,wake

四、完整示例:降低常驻进程优先级

复制代码
public class DaemonManager {
    
    private Context mContext;
    private PowerManager.WakeLock mWakeLock;
    
    public DaemonManager(Context context) {
        mContext = context;
        acquireWakeLock();
    }
    
    /**
     * 降低常驻进程优先级,使其更容易被系统查杀
     */
    public void lowerDaemonPriority() {
        // 1. 释放 WakeLock(如果持有的话)
        releaseWakeLock();
        
        // 2. 停止前台服务(如果运行着)
        stopForegroundService();
        
        // 3. 设置线程优先级为最低
        setLowThreadPriority();
        
        // 4. 设置进程组为后台组
        setBackgroundProcessGroup();
        
        // 5. 解绑系统服务连接
        unbindSystemServices();
        
        // 6. 请求系统回收内存
        requestMemoryCleanup();
    }
    
    private void acquireWakeLock() {
        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "DaemonManager:WakeLock");
        mWakeLock.acquire();
    }
    
    private void releaseWakeLock() {
        if (mWakeLock != null && mWakeLock.isHeld()) {
            mWakeLock.release();
            mWakeLock = null;
        }
    }
    
    private void stopForegroundService() {
        mContext.stopService(new Intent(mContext, MyDaemonService.class));
    }
    
    private void setLowThreadPriority() {
        android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_LOWEST);
    }
    
    private void setBackgroundProcessGroup() {
        try {
            android.os.Process.setProcessGroup(
                android.os.Process.myPid(),
                android.os.Process.THREAD_GROUP_BACKGROUND
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private void unbindSystemServices() {
        // 解绑系统服务连接
        // ...
    }
    
    private void requestMemoryCleanup() {
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        am.killBackgroundProcesses(mContext.getPackageName());
        System.gc();
    }
}

五、总结

关键要点
复制代码
- 用户应用的常驻服务 :完全可以降低优先级,使其更容易被查杀
- 系统级常驻进程 :不建议修改,可能影响系统稳定性
- WakeLock 的影响 :持有 WakeLock 的进程优先级更高,释放后更容易被杀
- 前台服务的影响 :前台服务优先级最高,停止后优先级大幅降低
相关推荐
笑一下蒜了.18 分钟前
Linux 存储多路径访问手册|multipath.conf 各配置段详解
android·linux·运维
凡泰AI22 分钟前
如何通过小程序多端框架,让一个小程序同时运行在iOS、安卓、鸿蒙以及PC客户端,实现一次开发多端运行的效果
android·ios·小程序
一笑的小酒馆1 小时前
Androidiot扫地机器人设备详情页地图加载慢卡顿优化方案
android
Zhu7587 小时前
在k8s集群部署MySQL单实例,支持多个主流发行版
android·mysql·kubernetes
AFinalStone10 小时前
Android 7系统异常问题排查(四)Framework层(上)—System Server Watchdog
android·系统异常
宝杰X712 小时前
Android Room3 多平台数据库
android·数据库
huibin14785236914 小时前
热缓解学习记录
android·学习
小田的博客17 小时前
SAP MM 供应商银行主数据更新报错!message R1228!
android·java·服务器
一笑的小酒馆18 小时前
Android智能猫砂盆视频加载慢卡顿问题分析
android
只会cv的小前端20 小时前
七巧低代码服务端脚本使用方法
android·低代码·rxjava