Android进程保活主流方案,retrofit原理

本文详细介绍了Android进程保活的几种主流方案,包括单进程广播守护、AIDL双进程守护和NDK双进程守护。通过这些方法,可以在一定程度上防止Android服务被系统杀死,确保后台任务的持续运行。然而,这些方法并不能完全抵抗用户手动强制停止应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目结构如下。

AndroidManifest.xml

//不加该权限会报错:java.lang.SecurityException: Permission Denial: startForeground from pid=XXX, uid=XXX requires android.permission.FOREGROUND_SERVICE


ForegroundService :模拟工作的(前台)线程,如有必要会开启ScapegoatService来清除通知栏通知。由于缺乏更多高版本系统样本,Android 8.0以上部分可能不靠谱,不过推荐还是老老实实按谷歌要求发出通知为妙。

package com.zyc.foregroundservice;

import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.RequiresApi;

import java.util.Timer;
import java.util.TimerTask;

public class ForegroundService extends Service {
private static final int SERVICE_ID = 1;
private Timer timer;
private TimerTask timerTask;
public static int count;

public ForegroundService() {
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
Log.d(MainActivity.TAG, “创建前台服务”);
}

@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startTask();

//判断版本
if (Build.VERSION.SDK_INT < 18) {//Android4.3以下版本
//直接调用startForeground即可,不会在通知栏创建通知
startForeground(SERVICE_ID, new Notification());

} else if (Build.VERSION.SDK_INT < 24) {//Android4.3 - 7.0之间
Intent scapegoatIntent = new Intent(this, ScapegoatService.class);
startService(scapegoatIntent);

} else {//Android 8.0以上
//经测试,本人的一加6T(Android 10)这样写并不会在通知栏创建通知,其他机型与版本效果仍需考证
startForeground(SERVICE_ID, new Notification());
}
return START_STICKY;
}

/**

  • 开启定时任务,count每秒+1
    */
    private void startTask() {
    timer = new Timer();
    timerTask = new TimerTask() {
    @Override
    public void run() {
    Log.d(MainActivity.TAG, "服务运行中,count: " + count);
    count++;
    }
    };
    timer.schedule(timerTask, 0, 1000);
    }

/**

  • 结束定时任务
    */
    private void stopTask() {
    if (timer != null) {
    timer.cancel();
    timer = null;
    }
    if (timerTask != null) {
    timerTask.cancel();
    timerTask = null;
    }
    count = 0;
    }

@Override
public void onDestroy() {
stopTask();
Log.d(MainActivity.TAG, “销毁前台服务”);
super.onDestroy();
}
}

ScapegoatService :拥有和工作线程相同id,启动后立马自行停止并销毁,也就替ForegroundService 消除了通知。

package com.zyc.foregroundservice;

import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;

public class ScapegoatService extends Service {
private static final int SERVICE_ID = 1; //后台ForegroundService的SERVICE_ID相同

public ScapegoatService() {
}

@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
super.onCreate();
Log.d(MainActivity.TAG, “创建前台服务替身”);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(SERVICE_ID, new Notification());
stopForeground(true);//移除通知栏消息
stopSelf();
return START_STICKY;
}

@Override
public void onDestroy() {
Log.d(MainActivity.TAG, “销毁前台服务替身”);
super.onDestroy();
}
}

MainActivity :启动/停止Service而已,不多赘述。

package com.zyc.foregroundservice;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity { <