项目中有很多业务有时需要保活,用笔者之前的项目举例。其中之一业务需要亮屏开门,app在后台情况下,点亮手机屏幕,需要做开门操作。在例如需要根据定位实时上报位置。这些前提都是app在后台,但是手机内存不足时,app会被系统回收,这时候就需要App进程保活,以及拉活处理。
App进程保活分为2种情况:
1:提高进程优先级,降低进程被杀死的概率
2:进程被杀之后,通过拉活
提高进程优先级,降低进程被杀死的概率,首先需要了解app的进程分类,分为以下5种。
1.前台进程-------Foreground process
某个进程持有一个正在与用户交互的Activity并且该Activity正处于resume的状态。
某个进程持有一个Service,并且该Service与用户正在交互的Activity绑定。
某个进程持有一个Service,并且该Service调用startForeground()方法使之位于前台运行。
某个进程持有一个Service,并且该Service正在执行它的某个生命周期回调方法,比如onCreate()、 onStart()或onDestroy()。
某个进程持有一个BroadcastReceiver,并且该BroadcastReceiver正在执行其onReceive()方法。
2.可见进程 —— Visible process
拥有不在前台、但仍对用户可见的 Activity(已调用 onPause())。
拥有绑定到可见(或前台)Activity 的 Service
3.服务进程 —— Service process
某个进程中运行着一个Service且该Service是通过startService()启动的,与用户看见的界面没有直接关联。
4,.后台进程 —— Background process
在用户按了"back"或者"home"后,程序本身看不到了,但是其实还在运行的程序,比如Activity调用了onPause方法
5.空进程-------Empty process 一般做缓存
某个进程不包含任何活跃的组件时该进程就会被置为空进程,完全没用,杀了它只有好处没坏处,第一个干它!
首先在activity中开启一个后台服务,为了防止主app内存过大被杀死,这个服务设置在其他进程中。
android:process=":process1"
在onCreat方法中注册一个开屏、锁屏的广播。
private void registerScreenStateReceiver() {
mScreenStateReceiver = new ScreenStateReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
intentFilter.addAction(ScreenStateReceiver.ACTION_SCREEN_ON_FAKE);
intentFilter.setPriority(1000);
registerReceiver(mScreenStateReceiver, intentFilter);
mScreenStateReceiver.setScreenStateListener(this);
}
广播接受者
public class ScreenStateReceiver extends BroadcastReceiver {
private boolean isScreenOn = true;
private ScreenStateListener listener;
public static final String ACTION_SCREEN_ON_FAKE = "actionScreenOnFake";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action) {
case ACTION_SCREEN_ON_FAKE:
if (listener != null) {
listener.fakeScreenOn();
}
break;
case Intent.ACTION_SCREEN_ON:
if (listener != null) {
listener.screenOn();
}
isScreenOn = true;
break;
case Intent.ACTION_SCREEN_OFF:
if (listener != null) {
listener.screenOff();
}
Intent intent2 = new Intent(ForeActivity.ACTION);
intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2.setPackage(context.getPackageName());
context.startActivity(intent2);
isScreenOn = false;
break;
}
}
public void setScreenStateListener(ScreenStateListener paramScreenStateListener) {
this.listener = paramScreenStateListener;
}
public interface ScreenStateListener {
public void screenOff();
public void screenOn();
public void fakeScreenOn();
}
}
在锁屏广播接受的时候,在屏幕左上角创建一个1像素的activity(该activity主题设置为透明)。在当前activity中也注册一个锁屏、亮屏的广播,在亮屏的时候关闭当前1像素的activity;在锁屏的时候可以做一些额外操作。
private void createOnePixelFloatView() {
Window window = getWindow();
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 0;
params.y = 0;
params.width = 1;
params.height = 1;
window.setAttributes(params);
}
广播拉活,Jobscheduler拉活现在不好用了
极光推送厂商通道了解一下,你在后台看不到厂商通道,开vip就好了
在主activity开启两个服务,两个服务中,相互开启对方,当对方服务被杀死之后,这样当自身服务被杀死之后,就会开启对方服务,相互类推。
当app被杀死之后,可以被拉活,其中账户拉活很常用,市面上通过账户拉活做法也很常见,例如腾讯系,阿里系的等。