1、说起双进程守护相信大家都不陌生了,就是一个兄弟A,一个兄弟B 两个人长大后都要自己去赚钱养家,例如兄弟A没赚到钱,然后兄弟B赚了很多钱,作为好兄弟肯定要拉一把,同样当兄弟A富有,兄弟B变穷的时候,同样兄弟A也需要拉兄弟B一把
目的就是双赢
我现在针对的是Android5.0一下盒子(已经root过)
首先需要创建一个BaseService 然后在创建一个KeepService直接在onCreate里面初始化
println("1111----BaseService onCreate")
keepService2()
println("2222----BaseService onCreate")
// startService(new Intent(this,DaHuaCamService.class));
object : Thread() {
override fun run() {
while (true) {
val isRun = Utils.isServiceWork(this@BaseService,
"com.hzx.homecenter2.service.KeepService")
if (isRun) {
val msg = Message.obtain()
msg.what = 1
m_Handler.sendMessage(msg)
}
try {
Thread.sleep(1)
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
}
}
thread.start()
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_STICKY
}
这个方法就不多说了相信大家都知道,就是service异常中断会重启,但是不能保证100%重启成功
internal var thread = Thread(Runnable {
val timer = Timer()
val task = object : TimerTask() {
override fun run() {
// Log.e(TAG, "ServiceTwo Run: " + System.currentTimeMillis());
val b = isServiceWorked()
if (!b) {
val service = Intent(this@BaseService, KeepService::class.java)
startService(service)
}
}
}
timer.schedule(task, 0, 1000)
})
检测当前有哪些Service允许
fun isServiceWorked(): Boolean {
val myManager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningService = myManager.getRunningServices(Integer.MAX_VALUE) as java.util.ArrayList
for (i in runningService.indices) {
if (runningService[i].service.className.toString() == "com.hzx.homecenter2.service.KeepService") {
return true
}
}
return false
OnTrimMemory是Android 4.0之后提供的API,系统会根据不同的内存状态来回调。系统提供的回调有:
Application.onTrimMemory()
Activity.onTrimMemory()
Fragement.OnTrimMemory()
Service.onTrimMemory()
ContentProvider.OnTrimMemory()
OnTrimMemory的参数是一个int数值,代表不同的内存状态:
TRIM_MEMORY_COMPLETE:内存不足,并且该进程在后台进程列表最后一个,马上就要被清理
TRIM_MEMORY_MODERATE:内存不足,并且该进程在后台进程列表的中部。
TRIM_MEMORY_BACKGROUND:内存不足,并且该进程是后台进程。
TRIM_MEMORY_UI_HIDDEN:内存不足,并且该进程的UI已经不可见了。
以上4个是4.0增加
TRIM_MEMORY_RUNNING_CRITICAL:内存不足(后台进程不足3个),并且该进程优先级比较高,需要清理内存
TRIM_MEMORY_RUNNING_LOW:内存不足(后台进程不足5个),并且该进程优先级比较高,需要清理内存
TRIM_MEMORY_RUNNING_MODERATE:内存不足(后台进程超过5个),并且该进程优先级比较高,需要清理内存
以上3个是4.1增加
/**
* 判断KeepService是否还在运行,如果不是则启动KeepService
*/
private fun keepService2() {
val isRun = Utils.isServiceWork(this@BaseService, "com.hzx.homecenter2.service.KeepService")
if (isRun == false) {
startS2.startService()
}
}
private val startS2: StrongService = object : StrongService {
override fun startService() {
val i = Intent(baseContext, KeepService::class.java)
baseContext.startService(i)
}
override fun stopService() {
val i = Intent(baseContext, KeepService::class.java)
baseContext.stopService(i)
}
}
实现Bind绑定
var myBinder = MyBinder()
override fun onBind(p0: Intent?): IBinder {
return startS2 as IBinder
}
inner class MyBinder : Binder() {
val service: BaseService
get() = this@BaseService
}
另外我设置的是全局启动 需要一个SampleApplicationLike是DefaultApplicationLike然后设置全局启动
IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK);//service结束无法重启修改,待验证
SampleApplicationLike.getInstance().getApplication().registerReceiver(checkServiceReceiver, filter);
通过一个TIME_TCIK Action去检测广播
private BroadcastReceiver checkServiceReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
boolean isServiceRunning = false;
if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
//检查Service状态
ActivityManager manager = (ActivityManager) SampleApplicationLike.getInstance().getApplication().getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo serviceInfo : manager.getRunningServices(Integer.MAX_VALUE)) {
if ("com.hzx.homecenter2.service.BaseService".equals(serviceInfo.service.getClassName())) {
isServiceRunning = true;
}
}
if (!isServiceRunning) {
Intent intent1 = new Intent(SampleApplicationLike.getInstance().getApplication(), KeepService.class);
intent.setFlags(intent1.FLAG_ACTIVITY_NEW_TASK);
SampleApplicationLike.getInstance().getApplication().startService(intent1);
}
}
}
};
下面是KeepService
package com.hzx.homecenter2.service
import android.app.ActivityManager
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.IBinder
import android.os.Message
import com.hzx.homecenter2.interfaces.StrongService
import com.hzx.homecenter2.util.Utils
import java.util.*
/**
* Created by carlosmx on 05/02/2018.
*/
class KeepService : Service() {
private val handler = object : Handler() {
override fun handleMessage(msg: Message) {
when (msg.what) {
1 -> {
keepService1()
}
else -> {
}
}
}
}
private val startS1: StrongService = object : StrongService {
override fun startService() {
val i = Intent(baseContext, BaseService.javaClass)
baseContext.startService(i)
println("1111----start BaseService")
}
override fun stopService() {
val i = Intent(baseContext, BaseService.javaClass)
baseContext.stopService(i)
}
}
override fun onTrimMemory(level: Int) {
keepService1()
}
override fun onCreate() {
super.onCreate()
println("1111----KeepService onCreate")
keepService1()
thread.start()
}
private fun keepService1() {
val isRun = Utils.isServiceWork(this@KeepService, "com.hzx.homecenter2.service.BaseService")
if (isRun == false) {
startS1.startService()
}
}
fun iServiceWork(): Boolean {
return false
}
internal var thread = Thread(Runnable {
val timer = Timer()
val task = object : TimerTask() {
override fun run() {
// Log.e(TAG, "ServiceTwo Run: " + System.currentTimeMillis());
val b = isServiceWorked()
if (!b) {
val service = Intent(this@KeepService, BaseService::class.java)
startService(service)
}
}
}
timer.schedule(task, 0, 1000)
})
override fun onBind(p0: Intent?): IBinder {
return startS1 as IBinder
}
fun isServiceWorked(): Boolean {
val myManager = this.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val runningService = myManager.getRunningServices(Integer.MAX_VALUE) as ArrayList
for (i in runningService.indices) {
if (runningService[i].service.className.toString() == "com.hzx.homecenter2.service.BaseService") {
return true
}
}
return false
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
// return START_REDELIVER_INTENT;
return START_STICKY
}
override fun onDestroy() {
super.onDestroy()
// if(thread!=null)
// {
// thread.interrupt()
// }
}
}
主Activity
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
System.out.println("seviceconnected :" + name);
Global.context = ((BaseService.MyBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Global.context = null;
System.out.println("servicedisconnected");
}
};
实现效果