Android 给App保活(10种方案)

1,427次阅读
没有评论

1.Activity 1像素保活
public class Activity1 extends AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_1);

    Window window = getWindow();
    window.setGravity(Gravity.LEFT|Gravity.TOP);
    WindowManager.LayoutParams layoutParams = window.getAttributes();
    layoutParams.width = 1;
    layoutParams.height = 1;
    layoutParams.x = 1;
    layoutParams.y = 1;
    window.setAttributes(layoutParams);
}

}

2.前台服务
public class ForegroundService extends Service {
private final static int SERVICE_ID = 1;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}

@Override
public void onCreate() {
    super.onCreate();

    if (Build.VERSION.SDK_INT<Build.VERSION_CODES.JELLY_BEAN_MR2){
        //4.3以下
        startForeground(SERVICE_ID,new Notification());
    }else if (Build.VERSION.SDK_INT<Build.VERSION_CODES.O){
        //7.0以下
        startForeground(SERVICE_ID,new Notification());
        //删除通知栏
        startService(new Intent(this,InnerService.class));
    }else {
        //8.0以上
        NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //NotificationManager.IMPORTANCE_MIN 通知栏消息的重要级别  最低,不让弹出
        //IMPORTANCE_MIN 前台时,在阴影区能看到,后台时 阴影区不消失,增加显示 IMPORTANCE_NONE时 一样的提示
        //IMPORTANCE_NONE app在前台没有通知显示,后台时有
        NotificationChannel channel = new NotificationChannel("channel", "keep", NotificationManager.IMPORTANCE_NONE);
        if (notificationManager!=null){
            notificationManager.createNotificationChannel(channel);
            Notification notification = new Notification.Builder(this, "channel").build();
            startForeground(SERVICE_ID,notification);
        }

    }
}


private static class InnerService extends Service{
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(KeepAliveApp.TAG, "onCreate: ");
        startForeground(SERVICE_ID,new Notification());
        stopSelf();
    }
}

}

3.广播拉活
在发生特定系统事件时,系统会发出广播,通过在 AndroidManifest 中静态注册对应的广播监听器,即可在发生响应事件时拉活。

    但是从android 7.0开始,对广播进行了限制,而且在8.0更加严格https://developer.android.google.cn/about/versions/oreo/background.html#broadcasts

    可静态注册广播列表: https://developer.android.google.cn/guide/components/broadcast-exceptions.html

4.利用系统机制拉活
START_STICKY:

“粘性”。如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。

START_NOT_STICKY:

“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。

START_REDELIVER_INTENT:

重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。

START_STICKY_COMPATIBILITY:

START_STICKY的兼容版本,但不保证服务被kill后一定能重启。

只要 targetSdkVersion 不小于5,就默认是 START_STICKY。 但是某些ROM 系统不会拉活。并且经过测试,Service 第一次被异常杀死后很快被重启,第二次会比第一次慢,第三次又会比前一次慢,一旦在短时间内 Service 被杀死4-5次,则系统不再拉起。

public class StickyService extends Service {

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

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return super.onStartCommand(intent, flags, startId);
}

}
5.账户同步拉活
/**

  • 创建 可添加用户
    */
    public class AuthenticationService extends Service { private AccountAuthenticator accountAuthenticator; @Nullable
    @Override
    public IBinder onBind(Intent intent) {
    return accountAuthenticator.getIBinder();
    } @Override
    public void onCreate() {
    super.onCreate();
    accountAuthenticator = new AccountAuthenticator(this);
    } public static class AccountAuthenticator extends AbstractAccountAuthenticator { public AccountAuthenticator(Context context) { super(context); } @Override public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) { return null; } @Override public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { return null; } @Override public String getAuthTokenLabel(String authTokenType) { return null; } @Override public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException { return null; } @Override public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException { return null; } }
    }

public class AccountHelper {
private static final String TAG = “AccountHelper”;

private static final String ACCOUNT_TYPE = "com.zsl.keepalive.account";
private static final String AUTHORITY = "com.zsl.keepalive.provider";

/**
 * 添加账号
 *
 * @param context
 */
public static void addAccount(Context context) {
    AccountManager accountManager = (AccountManager) context.getSystemService(Context.ACCOUNT_SERVICE);
    // 获得此类型的账户
    // 需要增加权限  GET_ACCOUNTS
    Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
    if (accounts.length > 0) {
        Log.e(TAG, "账户已存在");
        return;
    }
    Account account = new Account("zsl", ACCOUNT_TYPE);
    // 给这个账户类型添加一个账户
    // 需要增加权限  AUTHENTICATE_ACCOUNTS
    accountManager.addAccountExplicitly(account, "keepalive", new Bundle());
}

/**
 * 设置账户自动同步
 */
public static void autoSync() {
    Account account = new Account("zsl", ACCOUNT_TYPE);
    // 下面三个都需要同一个权限  WRITE_SYNC_SETTINGS
    // 设置同步
    ContentResolver.setIsSyncable(account, AUTHORITY, 1);
    // 自动同步
    ContentResolver.setSyncAutomatically(account, AUTHORITY, true);
    // 设置同步周期
    ContentResolver.addPeriodicSync(account, AUTHORITY, new Bundle(), 1);
}

}

public class SyncService extends Service {

private SyncAdapter mSyncAdapter;

private static final String TAG = "SyncService";

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return mSyncAdapter.getSyncAdapterBinder();
}

@Override
public void onCreate() {
    super.onCreate();
    mSyncAdapter = new SyncAdapter(getApplicationContext(), true);
}

public static class SyncAdapter extends AbstractThreadedSyncAdapter {

    public SyncAdapter(Context context, boolean autoInitialize) {
        super(context, autoInitialize);
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
        Log.e(TAG, "同步账户");
        //与互联网 或者 本地数据库同步账户
    }
}

}

public class SyncProvider extends ContentProvider {
@Override
public boolean onCreate() {
return false;
}

@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection,
                    @Nullable String[] selectionArgs, @Nullable String sortOrder) {
    return null;
}

@Nullable
@Override
public String getType(@NonNull Uri uri) {
    return null;
}

@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
    return null;
}

@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
    return 0;
}

@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection,
                  @Nullable String[] selectionArgs) {
    return 0;
}

}

6.JobScheduler拉活
JobScheduler允许在特定状态与特定时间间隔周期执行任务。可以利用它的这个特点完成保活的功能,效果即开启一个定时器,与普通定时器不同的是其调度由系统完成。 同样在某些ROM可能并不能达到需要的效果

public class KeepAliveJobService extends JobService {
@Override
public boolean onStartJob(JobParameters jobParameters) {
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.O){
startJob(this);
}
return false;
}

private void startJob(Context context) {
    JobScheduler jobScheduler = (JobScheduler) context.getSystemService(JOB_SCHEDULER_SERVICE);
    JobInfo.Builder builder = new JobInfo.Builder(27,
            new ComponentName(context.getPackageName(), KeepAliveJobService.class.getName()))
            .setPersisted(true);
    if (Build.VERSION.SDK_INT<Build.VERSION_CODES.N){
        builder.setPeriodic(1000);
    }else {
        builder.setMinimumLatency(1000);
    }
    jobScheduler.schedule(builder.build());

}

@Override
public boolean onStopJob(JobParameters jobParameters) {
    return false;
}

}

7.双进程守护
AIDL+JobScheduler 实现

// IMyAidlInterface.aidl
package com.zsl.keepalive;

// Declare any non-default types here with import statements

interface IMyAidlInterface {

}
public class LocalService extends Service {

private static final String TAG = "LocalService ";
private ServiceConnection serviceConnection;
private static final int SERVICE_ID = 16;
private MyBinder myBinder;

class MyBinder extends IMyAidlInterface.Stub {
}

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

@Override
public void onCreate() {
    super.onCreate();
    myBinder = new MyBinder();
    serviceConnection = new MyServiceConnection();

    // 让服务变成前台服务
    startForeground(SERVICE_ID, new Notification());
    // 如果18以上的设备 使用相同id再次启动一个前台服务 然后结束这个服务
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        startService(new Intent(this, InnerService.class));
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    bindService(new Intent(this, RemoteService.class),
            serviceConnection, BIND_AUTO_CREATE);
    return super.onStartCommand(intent, flags, startId);
}

class MyServiceConnection implements ServiceConnection {

    // 服务连接后回调
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    }

    // 连接中断后回调
    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.e(TAG, "RemoteService 可能被杀死了,拉活");

        startService(new Intent(LocalService.this, RemoteService.class));
        bindService(new Intent(LocalService.this, RemoteService.class),
                serviceConnection, BIND_AUTO_CREATE);
    }
}

public static class InnerService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        startForeground(SERVICE_ID, new Notification());
        stopSelf();
    }

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

}

public class RemoteService extends Service {

private static final String TAG = "RemoteService ";
private ServiceConnection serviceConnection;
private static final int SERVICE_ID = 16;
private MyBinder myBinder;
class MyBinder extends IMyAidlInterface.Stub {
}

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

@Override
public void onCreate() {
    super.onCreate();
    myBinder = new MyBinder();
    serviceConnection = new MyServiceConnection();

    // 让服务变成前台服务
    startForeground(SERVICE_ID, new Notification());
    // 如果18以上的设备 使用相同id再次启动一个前台服务 然后结束这个服务
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
        startService(new Intent(this, InnerService.class));
    }
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    bindService(new Intent(this, LocalService.class),
            serviceConnection, BIND_AUTO_CREATE);
    return super.onStartCommand(intent, flags, startId);
}

class MyServiceConnection implements ServiceConnection {

    // 服务连接后回调
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    }

    // 连接中断后回调
    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.e(TAG, "LocalService 可能被杀死了,拉活");

        startService(new Intent(RemoteService.this, LocalService.class));
        bindService(new Intent(RemoteService.this, LocalService.class),
                serviceConnection, BIND_AUTO_CREATE);
    }
}

public static class InnerService extends Service {

    @Override
    public void onCreate() {
        super.onCreate();
        startForeground(SERVICE_ID, new Notification());
        stopSelf();
    }

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

}

KeepAliveJobService .java

@Override
public boolean onStartJob(JobParameters params) {
Log.e(TAG, “onStartJob”);

    // 如果7.0以上 轮询
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
        startJob(this);
    }
    boolean isLocal = Utils.isRunningService(this, LocalService.class.getName());
    boolean isRemote = Utils.isRunningService(this, RemoteService.class.getName());
    if (!isLocal || !isRemote) {
        startService(new Intent(this, LocalService.class));
        startService(new Intent(this, RemoteService.class));
    }
    return false;
}

public class Utils {

public static boolean isRunningService(Context context, String name) {
    ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningServiceInfo> runningServices = am.getRunningServices(100);
    for (ActivityManager.RunningServiceInfo info : runningServices) {
        if (TextUtils.equals(info.service.getClassName(), name)) {
            return true;
        }
    }
    return false;
}

}
8.播放无声音乐

9.WorkManager
public class KeepLiveWork extends Worker {

public KeepLiveWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
    super(context, workerParams);
}

@NonNull
@Override
public Result doWork() {
    Log.e("KeepAlive", "doWork: ");

    KeepAliveJobService.startJob(getApplicationContext());

    return Result.success();
}

}

添加任务

OneTimeWorkRequest oneTimeWorkRequest = new OneTimeWorkRequest
.Builder(KeepLiveWork.class)
.setInitialDelay(10, TimeUnit.SECONDS)
.build();

    WorkManager.getInstance(this).enqueue(oneTimeWorkRequest);

10.厂商白名单
终极保活,需要厂商定制

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)

文心AIGC

2023 年 9 月
 123
45678910
11121314151617
18192021222324
252627282930  
文心AIGC
文心AIGC
人工智能ChatGPT,AIGC指利用人工智能技术来生成内容,其中包括文字、语音、代码、图像、视频、机器人动作等等。被认为是继PGC、UGC之后的新型内容创作方式。AIGC作为元宇宙的新方向,近几年迭代速度呈现指数级爆发,谷歌、Meta、百度等平台型巨头持续布局
文章搜索
热门文章
清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开

清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开

清库存!DeepSeek突然补全R1技术报告,训练路径首次详细公开 Jay 2026-01-08 20:18:...
训具身模型遇到的很多问题,在数据采集时就已经注定了丨鹿明联席CTO丁琰分享

训具身模型遇到的很多问题,在数据采集时就已经注定了丨鹿明联席CTO丁琰分享

训具身模型遇到的很多问题,在数据采集时就已经注定了丨鹿明联席CTO丁琰分享 衡宇 2026-01-08 20:...
「北京版幻方」冷不丁开源SOTA代码大模型!一张3090就能跑,40B参数掀翻Opus-4.5和GPT-5.2

「北京版幻方」冷不丁开源SOTA代码大模型!一张3090就能跑,40B参数掀翻Opus-4.5和GPT-5.2

「北京版幻方」冷不丁开源SOTA代码大模型!一张3090就能跑,40B参数掀翻Opus-4.5和GPT-5.2...
开源“裸考”真实世界,国产具身智能基座模型拿下全球第二!

开源“裸考”真实世界,国产具身智能基座模型拿下全球第二!

开源“裸考”真实世界,国产具身智能基座模型拿下全球第二! 西风 2026-01-08 19:02:20 来源:...
最新评论
ufabet ufabet มีเกมให้เลือกเล่นมากมาย: เกมเดิมพันหลากหลาย ครบทุกค่ายดัง
tornado crypto mixer tornado crypto mixer Discover the power of privacy with TornadoCash! Learn how this decentralized mixer ensures your transactions remain confidential.
ดูบอลสด ดูบอลสด Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Pretty! This has been a really wonderful post. Many thanks for providing these details.
ดูบอลสด ดูบอลสด Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
Obrazy Sztuka Nowoczesna Obrazy Sztuka Nowoczesna Thank you for this wonderful contribution to the topic. Your ability to explain complex ideas simply is admirable.
ufabet ufabet Hi there to all, for the reason that I am genuinely keen of reading this website’s post to be updated on a regular basis. It carries pleasant stuff.
ufabet ufabet You’re so awesome! I don’t believe I have read a single thing like that before. So great to find someone with some original thoughts on this topic. Really.. thank you for starting this up. This website is something that is needed on the internet, someone with a little originality!
ufabet ufabet Very well presented. Every quote was awesome and thanks for sharing the content. Keep sharing and keep motivating others.
热评文章
悲报!Stack Overflow彻底凉了,比18年前上线首月问题数量还少

悲报!Stack Overflow彻底凉了,比18年前上线首月问题数量还少

悲报!Stack Overflow彻底凉了,比18年前上线首月问题数量还少 闻乐 2026-01-05 19:...
全自主、更好用!北京人形 “干活机器人” 惊艳亮相 CES2026

全自主、更好用!北京人形 “干活机器人” 惊艳亮相 CES2026

全自主、更好用!北京人形 “干活机器人” 惊艳亮相 CES2026 量子位的朋友们 2026-01-06 16...
港科大教授实测AI眼镜“作弊”:30分钟碾压95%的学生,把传统教学评估体系整破防了

港科大教授实测AI眼镜“作弊”:30分钟碾压95%的学生,把传统教学评估体系整破防了

港科大教授实测AI眼镜“作弊”:30分钟碾压95%的学生,把传统教学评估体系整破防了 梦瑶 2026-01-0...
海信CES发布全新一代RGB-Mini LED,全球首创玲珑4芯真彩背光

海信CES发布全新一代RGB-Mini LED,全球首创玲珑4芯真彩背光

海信CES发布全新一代RGB-Mini LED,全球首创玲珑4芯真彩背光 量子位的朋友们 2026-01-06...