QQ为什么一直常驻后台?
(白名单,双进程守护)
应用正在运行,这个时候内存不足回收杀进程
- 1.提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),如启动Service调用startForeground()尽量提高进程的优先级;
- 2.当应用退到后台适当释放资源然后降低APP的内存占用量,因为在oom_adj相同的时候,会优先干掉内存消耗大的进程;
双进程守护
MessageService
public class MessageService extends Service {
private static final String TAG = MessageService.class.getSimpleName();
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
Log.e("TAG", "等待接收消息");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//提高进程优先级
//提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),
// 如启动Service调用startForeground()尽量提高进程的优先级;
startForeground(1, new Notification());
//绑定服务
bindService(new Intent(this, GuardService.class), mConnService, BIND_IMPORTANT);
return START_STICKY;
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new ProcessAidl.Stub() {
};
}
private ServiceConnection mConnService = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//绑定连接
Toast.makeText(MessageService.this, "建立连接", Toast.LENGTH_LONG).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//解绑 重新启动 绑定服务
startService(new Intent(MessageService.this, GuardService.class));
//绑定服务
bindService(new Intent(MessageService.this, GuardService.class), mConnService, Context.BIND_IMPORTANT);
}
};
}
GuardService
public class GuardService extends Service {
private static final String TAG = GuardService.class.getSimpleName();
@Nullable
@Override
public IBinder onBind(Intent intent) {
return new ProcessAidl.Stub() {
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//提高进程优先级
//提高进程的优先级,其实就是减小进程的p->oomkilladj(越小越重要),
// 如启动Service调用startForeground()尽量提高进程的优先级;
startForeground(1, new Notification());
//绑定服务
bindService(new Intent(this, MessageService.class), mConnService, BIND_IMPORTANT);
return START_STICKY;
}
private ServiceConnection mConnService = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//绑定连接
Toast.makeText(GuardService.this, "建立连接", Toast.LENGTH_LONG).show();
}
@Override
public void onServiceDisconnected(ComponentName name) {
//解绑 重新启动 绑定服务
startService(new Intent(GuardService.this, MessageService.class));
//绑定服务
bindService(new Intent(GuardService.this, MessageService.class), mConnService, BIND_IMPORTANT);
}
};
}
ProcessAidl:空的Aidl
interface ProcessAidl {
}
此时我们可以发现我们软件是有双进程的,我们停止停不了,用了系统自带或者第三方的清理软件,也不会杀我们的进程,但是各大Rom厂商在应用退出的时候会清理杀进程。解决方法可以使用ndk,这里使用电量优化的方法
JobWakeUpService
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public class JobWakeUpService extends JobService {
private final int jobWakeUpId = 1;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
JobInfo.Builder builder = new JobInfo.Builder(jobWakeUpId,
new ComponentName(this, JobWakeUpService.class));
builder.setPeriodic(2000);
// 开启一个轮寻
JobScheduler jobScheduler = (JobScheduler) getSystemService(Context.JOB_SCHEDULER_SERVICE);
jobScheduler.schedule(builder.build());
return START_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
// 开启定时任务,定时轮寻 , 看MessageService有没有被杀死
// 如果杀死了启动 轮寻onStartJob
boolean messageServiceAlive = serviceAlive(MessageService.class.getName());
if (!messageServiceAlive) {
startService(new Intent(this, MessageService.class));
}
return false;
}
@Override
public boolean onStopJob(JobParameters params) {
return false;
}
/**
* 判断某个服务是否正在运行的方法
*
* @param serviceName 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
* @return true代表正在运行,false代表服务没有正在运行
*/
private boolean serviceAlive(String serviceName) {
boolean isWork = false;
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> myList = manager.getRunningServices(100);
if (myList.size() < 0) {
return false;
}
for (ActivityManager.RunningServiceInfo info : myList) {
if (info.service.getClassName().equals(serviceName)) {
isWork = true;
return true;
}
}
return isWork;
}
}
配置manifest.xml文件
<service
android:name=".MessageService"
android:enabled="true"
android:exported="true" />
<!--android:process=":guardProgress" 新建一个线程-->
<service
android:name=".GuardService"
android:process=":guardService" />
<service
android:name=".JobWakeUpService"
android:permission="android.permission.BIND_JOB_SERVICE" />
一定要添加权限:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />