2015年4月1日 星期三

[Android] About Service - how to keep Service running permanently?

As described in [Android] About Service - will Service be Killed?,the Service will be restarted after being killed.
However, what if the system does not restart it?
Is there any other way that we can keep our Service running permanently?

A simple way is to establish another service called "monitorService".
Its job is to monitor our service myService
When it finds that myService is not in the RUNNING list, it will restart myService.

As described in [Android] How to load my APP automatically after system booting upthere has one class BootUpReceiverClass.java to receive the message from system after booting up.
Actually, we can use it to receive the Broadcast messages as well.
We need to add one intent-filter in AndroidManifest.xml.
<receiver android:enabled="true" android:name="myTest.com.BootUpReceiverClass"
 android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
 <intent-filter>
 <action android:name="android.intent.action.BOOT_COMPLETED" />
 <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>
 <intent-filter>
 <action android:name="myTest.com.BootUpReceiverClass" /> 
 <category android:name="android.intent.category.DEFAULT" />       
 </intent-filter>
</receiver> 

For monitorService part, we have one thread monitorThread to check if "myTest.com.myServiceClass" is running or not.
If not, it will call sendBroadcast() to send the event to "myTest.com.BootUpReceiverClass".
private boolean isMyServiceRunning(String className) {
  try
  {
      ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
      for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {       
          if (className.equals(service.service.getClassName())) {
              return true;
          }
      }
  }catch (Exception e) {   
   e.printStackTrace();   
  }
     return false;
 }
 private class monitorThread extends Thread {
  @Override
  public void run() {
   super.run();   
   while(!isInterrupted()) {
    try {     
     if(!isMyServiceRunning("myTest.com.myServiceClass"))
     {      
      try
      {
       Intent intent = new Intent("myTest.com.BootUpReceiverClass");
       if(intent!=null)
       {        
           sendBroadcast(intent);
                 Thread.sleep(15000);
       }
      }catch (Exception e) {       
       e.printStackTrace();       
      }
     } 
     else
     {      
      Thread.sleep(3000);
     }     
    } catch (InterruptedException e) {     
     e.printStackTrace();     
    }
   }   
  }
 }
What if monitorService is killed?
To avoid such condition, we need to add a similar mechanism in myService.
It will check if monitorService is running or not.
If not, just restart it.
The codes are not posted here since they are similar.

In general, it is enough to check mutually for every 2~5 seconds.
You can check if both myService and monitorService are there in the RUNNING list.
Try to kill myService manually and check if it will be restarted.
On the other hand, try to kill monitorService manually and check if it will be restarted.

What if both monitorService and myService are killed at the same time?
It is hard to do that manually. You can try it by yourself.
The possible way is to kill them both by system.
It means that the system loading should be heavy.
Is such case, our service will not run smoothly even it survives.

沒有留言:

張貼留言