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<ActivityManager.RunningServiceInfo> for (i in runningService.indices) { if (runningService[i].service.className.toString() == "com.hzx.homecenter2.service.KeepService") { return true } } return falseOnTrimMemory是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<ActivityManager.RunningServiceInfo> 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"); } };
实现效果