The emergency service has restarted after a very long time

I am running the service in the foreground. Sometimes it ends, presumably for memory reasons (although I'm not 100% sure from LogCat). Other services that are completed are scheduled to restart in 5000 ms, but looking at the log, the reboots of my service are very long, for example:

11-15 15:39:48.756: W/ActivityManager(375): Scheduling restart of crashed service com.example.app/com.example.SensorService in 1019562ms 

What could explain this? How is the restart interval set? I saw some suggestions that notification services restart with a shorter delay, but my service has a notification.

+6
source share
3 answers

From com / android / server / am / ActiveServices.java (not displayed)

 // How long we wait for a service to finish executing. static final int SERVICE_TIMEOUT = 20*1000; // How long a service needs to be running until restarting its process // is no longer considered to be a relaunch of the service. static final int SERVICE_RESTART_DURATION = 5*1000; // How long a service needs to be running until it will start back at // SERVICE_RESTART_DURATION after being killed. static final int SERVICE_RESET_RUN_DURATION = 60*1000; // Multiplying factor to increase restart duration time by, for each time // a service is killed before it has run for SERVICE_RESET_RUN_DURATION. static final int SERVICE_RESTART_DURATION_FACTOR = 4; // The minimum amount of time between restarting services that we allow. // That is, when multiple services are restarting, we won't allow each // to restart less than this amount of time from the last one. static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; // Maximum amount of time for there to be no activity on a service before // we consider it non-essential and allow its process to go on the // LRU background list. static final int MAX_SERVICE_INACTIVITY = 30*60*1000; 

For you, your service probably dies faster, and then SERVICE_RESET_RUN_DURATION , and then the restart time is multiplied by SERVICE_RESTART_DURATION_FACTOR .

Starting at line # 881:

  // If it has been a "reasonably long time" since the service // was started, then reset our restart duration back to // the beginning, so we don't infinitely increase the duration // on a service that just occasionally gets killed (which is // a normal case, due to process being killed to reclaim memory). if (now > (r.restartTime+resetTime)) { r.restartCount = 1; r.restartDelay = minDuration; } else { if ((r.serviceInfo.applicationInfo.flags &ApplicationInfo.FLAG_PERSISTENT) != 0) { // Services in peristent processes will restart much more // quickly, since they are pretty important. (Think SystemUI). r.restartDelay += minDuration/2; } else { r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; if (r.restartDelay < minDuration) { r.restartDelay = minDuration; } } } 

The line below rolls back your service.

 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR; 

So you have to fix the case if your service dies before starting for SERVICE_RESET_RUN_DURATION .

+14
source

First of all, I think that you will call the Service class from the Activity class or from any BroadCastReceiver class.

You want to start the service after a certain or after 5000ms. Although your question is not clear to me. However, to my knowledge, you should call a service from your class of service. For instance:

  public class UpdateWidgetServiceDemo extends Service { public static int numberOfItems=0; String resultURL=""; //numberOfItems=0; private static String LOG = "testwidgets"; ArrayList<String> feedsPubDate; @TargetApi(Build.VERSION_CODES.GINGERBREAD) @SuppressWarnings("deprecation") @Override public void onStart(Intent intent, int startId) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); Log.i(LOG, "Called"); // Create some random data feedsPubDate=new ArrayList<String>(); ///////////////////////////////////////////////////////////////////// // SharedPreferences sp = getSharedPreferences("updateOptions", 0); // int updatePeriod=sp.getInt("UpdatePeriod", -1); Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, 10); Intent intent1 = new Intent(this, UpdateWidgetServiceDemo.class); PendingIntent pintent = PendingIntent.getService(this, 0, intent1, 0); AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE); int i; i=15; alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), i* 1000, pintent); } . . . 

The important part is important here:

 Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, 10); Intent intent1 = new Intent(this, UpdateWidgetServiceDemo.class); PendingIntent pintent = PendingIntent.getService(this, 0, intent1, 0); AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE); int i; i=15; alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), i* 1000, pintent); 

I think your problem will be solved.

Enjoy !!!

+2
source

You can set the update interval using the method below, the service will restart every 1 minute .:

 void setServiceIntervalAlarm() { // set alarm for next 60 seconds Intent updateIntent = new Intent(); updateIntent.setClass(this, CheckOutRequestsService.class); PendingIntent pendingIntent = PendingIntent.getService(this, 23, updateIntent, 0); // Schedule alarm, and force the device awake for this update AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); long nextUpdate = 60000; alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), nextUpdate, pendingIntent); } 
+1
source

Source: https://habr.com/ru/post/958178/


All Articles