昨天晚上写了用系统服务等方法来实现应用保活。今天写一下用提高app的进程等级来实现应用保活。想看直接调用系统方法保活应用的可以点击Android进程守护,让APP在系统内存中常驻(一)进行跳转。
一:第一种实现思路,创建广播接收者来监听系统关屏亮屏操作。当手机关屏时,显示一个透明的一像素的activity,此时用户时看不见的;当手机亮屏时,把这个activity给finish掉。好了,有了思路就开始实现吧。
1.首先新建一个广播接收者:来判断当前的屏幕状态来进行一些操作。
public class AppBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())){
AppReciver.getInstance().startApp(context);
}else {
AppReciver.getInstance().finishApp();
}
}
}
2.创建一个1像素的activity。
@SuppressLint("RtlHardcoded")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_null);
//设置1像素
Window window = getWindow();
window.setGravity(Gravity.LEFT | Gravity.TOP);
WindowManager.LayoutParams params = window.getAttributes();
params.x = 0;
params.y = 0;
params.height = 1;
params.width = 1;
window.setAttributes(params);
//用来给单例传过去activity,能让它finish掉。
AppReciver.getInstance().setActivity(this);
}
3.为这个活动创建一个空的透明的主题。
4.为这个活动修改AndroidManifest中的内容,把它单独放入一个栈中。让他使用刚刚为他创建的主题。
5.创建一个单例,用来完成开始和结束活动任务的逻辑操作。
class AppReciver {
private static final AppReciver ourInstance = new AppReciver();
private WeakReference weakReference;
private AppReciver() {
}
static AppReciver getInstance() {
return ourInstance;
}
public void startApp(Context context) {
context.startActivity(new Intent(context, NullActivity.class));
}
public void registerReceiver(Context context) {
AppBroadcastReceiver appBroadcastReceiver = new AppBroadcastReceiver();
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");
context.registerReceiver(appBroadcastReceiver, intentFilter);
}
public void finishApp() {
if (weakReference != null && weakReference.get() != null) {
weakReference.get().finish();
}
}
public void setActivity(NullActivity activity) {
weakReference = new WeakReference(activity);
}
}
6.注意上面的单例中使用了WeakReference来保存activity。这里为了避免内存泄漏使用了弱引用。最后在活动中调用一下就完成了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.系统拉活service进程
//startService(new Intent(this,StickService.class));
//2.通过jobScheduler拉活
//startJob();
//3.通过bindService,通过ServiceConnection来拉活
//bindService();
//4.通过activity来提升app的进程等级
AppReciver.getInstance().registerReceiver(this);
}
二:service提升app的进程等级
1.首先新建一个服务。
public class ForegroundService extends Service {
private static final int SERVICE_ID = 1;
public ForegroundService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
2.如果是安卓4.0以下可以直接构建一个空的通知。安卓8.0以上,通知需要设置channel ,还需要设置通知的重要级别 ,安卓9.0以上,通知会直接显示出来。所以要进行版本的判断,来实现通知的设置方式。4.0以下的可以直接通过下面一行代码调用。
if (Build.VERSION.SDK_INT < 18) {
//安卓4.0以下可以直接构建一个空的通知。
//设置成前台服务,并且去除通知栏消息
startForeground(SERVICE_ID,new Notification());
}
3.安卓8.0以下的就需要先设置成前台服务,然后再去通过新的服务去除通知栏的消息。好了,废话不说,直接上代码。
else if (Build.VERSION.SDK_INT < 26) {
//设置成前台服务
startForeground(SERVICE_ID,new Notification());
//并且去除通知栏消息
startService(new Intent(this,InnerService.class));
}
4.InnerService直接写一个内部服务就行。在里面进行去除通知栏的消息。
private class InnerService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(SERVICE_ID,new Notification());
stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
}
5.下面是这个服务的完整代码。
public class ForegroundService extends Service {
private static final int SERVICE_ID = 1;
public ForegroundService() {
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT < 18) {
//安卓4.0以下可以直接构建一个空的通知。
//设置成前台服务,并且去除通知栏消息
startForeground(SERVICE_ID,new Notification());
} else if (Build.VERSION.SDK_INT < 26) {
//设置成前台服务
startForeground(SERVICE_ID,new Notification());
//并且去除通知栏消息
startService(new Intent(this,InnerService.class));
} else {
//安卓8.0以上,通知需要设置channel
//还需要设置通知的重要级别
//安卓9.0以上,通知会直接显示出来。
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (manager!=null){
NotificationChannel channel = new NotificationChannel("channel","xxx",NotificationManager.IMPORTANCE_NONE);
manager.createNotificationChannel(channel);
Notification notification = new NotificationCompat.Builder(this,"channel").build();
startForeground(SERVICE_ID,notification);
}
}
return super.onStartCommand(intent, flags, startId);
}
private class InnerService extends Service{
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(SERVICE_ID,new Notification());
stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
}
}
6.在活动中启动一下就大功告成了。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//1.系统拉活service进程
//startService(new Intent(this,StickService.class));
//2.通过jobScheduler拉活
//startJob();
//3.通过bindService,通过ServiceConnection来拉活
//bindService();
//4.通过activity来提升app的进程等级
//AppReciver.getInstance().registerReceiver(this);
//5.通过Service来提升app的进程等级
startService(new Intent(this,ForegroundService.class));
}
好了,就说到这吧,有什么补充的或者哪里说的不对的欢迎在下面评论,一期交流,相互学习。