安卓App如何在后台运行时和息屏时保活(综合篇)

一、前言
    通常做通话和即时通讯应用,都存在app保活的问题,一旦切换到后台或者息屏时候,每个手机都会有不同程度对应用按优先级进行管理,按照优先级从低到高冻结(Freeze)和杀死(Kill)。但是通话和即时通讯应用被杀死之后,就无法及时收到通知进行通讯,这无疑是一个问题。
二、步骤
    在网上查阅大量资料。无外乎以下几种方案:1.双进程守护;2.1像素保活;3.设置为前台应用;4.Jobscheduler执行任务调度。我个人觉得1和4在很多场景下都不太适合,不是什么应用能接受重启的机制。所以就把希望寄托1像素保活和设置前台应用。相关文章都有人点赞和收藏,但是这两种都试了,都达不到效果。因为不同的手机系统杀死后台应用的严厉程度不尽相同。后来我结合这两种方法,在我这个非常容易杀死后台应用的手机系统上实现了保活效果。以下是我的思路和步骤:

1、App保活的场景

(1)App切换后台之后玩其他应用;

(2)App在前台,直接息屏;

(3)App切换到后台之后,再息屏。

2、设置前台应用作为1像素保活的基础

3、在第一种场景下,可以显示1像素悬浮框的方式;第二种场景,可以和第三种场景一样,在息屏的时候都弹出一个1像素界面,在息屏的时候弹出,在亮屏的时候销毁。

4、代码部分:

(1)进入app,在service里注册亮屏息屏接收器,并显示1像素悬浮窗。

KeepAliveManager.getInstance().registerReceiver(this); //注册广播接收者

//注册主体代码

mHideFloatingView =new HideFloatingView(context);//1像素悬浮窗

mStateReceiver =new ScreenStateReceiver();

IntentFilter intentFilter =new IntentFilter();

intentFilter.addAction(“android.intent.action.SCREEN_OFF”);

intentFilter.addAction(“android.intent.action.SCREEN_ON”);

intentFilter.addAction(“android.intent.action.USER_PRESENT”);

mContext.registerReceiver(mStateReceiver, intentFilter);

mHideFloatingView.show(); //悬浮窗随应用启动直接显示

(2)在接收者里处理亮屏和黑屏的事件,息屏的时候,弹出1像素activity。

public class ScreenStateReceiver extends BroadcastReceiver {

@Override

public void onReceive(Context context,Intent intent) {

if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {//屏幕关闭启动1像素Activity

        Log.i(TAG,"onReceive: 息屏");

mHideFloatingView.dismiss(); //息屏的时候1像素悬浮窗remove消失

startActivity(); //启动1像素activity界面

}else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {//屏幕打开 结束1像素

        Log.i(TAG,"onReceive: 亮屏");

mHideFloatingView.show(); //亮屏1像素悬浮窗add显示,activity会在它自己的onResume里finish

}

}

}

public void startActivity() {

Intent it =new Intent(mContext,KeepAliveActivity.class);

it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

mContext.startActivity(it);

}

(3)1像素保活的基础,把service设置为前台服务。

if (Build.VERSION.SDK_INT <18) {//Android4.3以下版本

//将Service设置为前台服务,可以取消通知栏消息

startForeground(SERVICE\_ID,new Notification());

Log.i(TAG,“onStartCommand: 111”);

}else if (Build.VERSION.SDK_INT <24) {//Android4.3 - 7.0之间

Log.i(TAG,"onStartCommand: 222");

//将Service设置为前台服务,可以取消通知栏消息

startForeground(SERVICE\_ID,new Notification());

startService(new Intent(this,InnerService.class));

}else {//Android 8.0以上

Log.i(TAG,"onStartCommand:333 ");

NotificationManager manager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);

if (manager !=null) {

NotificationChannel channel =null;

if (Build.VERSION.SDK_INT >=Build.VERSION_CODES.O) {

channel =new NotificationChannel(CHANNEL_ID,“abc”,NotificationManager.IMPORTANCE_NONE);

manager.createNotificationChannel(channel);

}

Notification notification =new NotificationCompat.Builder(this,CHANNEL_ID).build();

//将Service设置为前台服务,Android 8.0 App启动不会弹出通知栏消息,退出后台会弹出通知消息

    //Android9.0启动时候会立刻弹出通知栏消息

    startForeground(SERVICE\_ID, notification);

}

}

public static class InnerService extends Service {

@Override

public IBinder onBind(Intent intent) {

return null;

}

@Override

public int onStartCommand(Intent intent,int flags,int startId) {

Log.i(TAG,“onStartCommand: 99999999999999”);

startForeground(SERVICE_ID,new Notification());

stopForeground(true);//移除通知栏消息

    stopSelf();

return super.onStartCommand(intent,flags,startId);

}

}

如果你看到了这里,觉得文章写得不错就给个赞呗?
更多Android进阶指南 可以扫码 解锁更多Android进阶资料


在这里插入图片描述
敲代码不易,关注一下吧。ღ( ´・ᴗ・` )

  • 29
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值