1.常见问题
- 1.内存不够用的时候,系统会按照进程的优先级回收内存
解决方案:提高应用的优先级,startForeground - 2.三方软件清理,原理是一个一个的杀进程,相当于手动杀进程
解决方案:开启双进程互相唤醒 - 3.定制ROOM的系统,如小米,魅族,在应用关掉时,会杀掉应用的所有进程()
解决方案:使用JobSchedule,开启定时任务,当进程被杀死时,重新启动(5.0以上支持)
2.方案具体实现
2.1 提高进程的优先级
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//这样做会在手机主界面创建一个通知栏,将服务所在进程提升为前台进程
startForeground(100,new Notification());
return super.onStartCommand(intent, flags, startId);
}
2.2 开启双进程守护
- 新建一个aidl文件
interface ServiceAidl {
void processConnected();
}
2.目标服务
/**
*目标服务
*@author woochen123
*@time 2017/8/25 11:20
*@desc
*/
public class MyService extends Service {
private static final String TAG = "MyService";
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected: 连接成功2");
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected: 连接失败2" );
//重新启动守护服务并绑定
Intent intent = new Intent(MyService.this, GuardService.class);
startService(intent);
bindService(intent,conn,BIND_IMPORTANT);
}
};
public MyService() {
}
@Override
public void onCreate() {
super.onCreate();
new Thread(new Runnable() {
@Override
public void run() {
while (true){
Log.e(TAG, "run: 接收消息");
SystemClock.sleep(3000);
}
}
}).start();
}
@Override
public IBinder onBind(Intent intent) {
return mBind;
}
ServiceAidl.Stub mBind = new ServiceAidl.Stub() {
@Override
public void processConnected() throws RemoteException {
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(100,new Notification());
bindService(new Intent(this,GuardService.class),conn,BIND_IMPORTANT);
return super.onStartCommand(intent, flags, startId);
}
}
3.守护服务
/**
*守护服务
*@author woochen123
*@time 2017/8/25 9:52
*@desc
*/
public class GuardService extends Service {
private static final String TAG = "GuardService";
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
Log.e(TAG, "onServiceConnected: 连接成功1" );
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
Log.e(TAG, "onServiceDisconnected: 连接失败1" );
//重新启动目标服务并绑定
Intent intent = new Intent(GuardService.this, MyService.class);
startService(intent);
bindService(intent,conn, BIND_IMPORTANT);
}
};
public GuardService() {
}
@Override
public IBinder onBind(Intent intent) {
return mbind;
}
ServiceAidl.Stub mbind = new ServiceAidl.Stub() {
@Override
public void processConnected() throws RemoteException {
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand: 绑定守护服务开始" );
bindService(new Intent(GuardService.this,MyService.class),conn, BIND_IMPORTANT);
return START_STICKY;
}
}
2.3 JobSchedule启动定时任务(5.0以上适用)
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name=".service.AwakeService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:enabled="true"
android:exported="true"></service>
/**
* 唤醒进程
*
* @author woochen123
* @time 2017/8/25 11:25
* @desc
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public class AwakeService extends JobService {
private static final String TAG = "AwakeService";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
JobScheduler jobScheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
ComponentName jobService = new ComponentName(this, AwakeService.class);
JobInfo.Builder jobInfo = new JobInfo.Builder(1, jobService);
//延迟5s执行
jobInfo.setPeriodic(2000);
jobScheduler.schedule(jobInfo.build());
return START_STICKY;
}
@Override
public boolean onStartJob(JobParameters jobParameters) {
Log.e(TAG, "onStartJob: ");
//判断目的服务是否还存活
boolean isAlive = isServiceWork(this, MyService.class.getName());
Log.e(TAG, "onStartJob: 服务存活" +isAlive);
if (!isAlive) {
Log.e(TAG, "onStartJob: 重启服务" );
startActivity(new Intent(this, MyService.class));
}
return false;
}
@Override
public boolean onStopJob(JobParameters jobParameters) {
Log.e(TAG, "onStopJob: ");
return false;
}
/**
* 判断某个服务是否正在运行的方法
*
* @param mContext
* @param serviceName 是包名+服务的类名(例如:net.loonggg.testbackstage.TestService)
* @return true代表正在运行,false代表服务没有正在运行
*/
public boolean isServiceWork(Context mContext, String serviceName) {
boolean isWork = false;
ActivityManager myAM = (ActivityManager) mContext
.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> myList = myAM.getRunningServices(100);
if (myList.size() <= 0) {
return false;
}
for (int i = 0; i < myList.size(); i++) {
String mName = myList.get(i).service.getClassName().toString();
if (mName.equals(serviceName)) {
isWork = true;
break;
}
}
return isWork;
}
}
网友评论