loop in IntentService

Jason Ching picture Jason Ching · Aug 18, 2012 · Viewed 8.5k times · Source

I have an infinite loop in my IntentService to update my view once every 30 seconds based on the input from the main activity.

public class IntentServiceTest extends IntentService {

String Tag = "IntentServiceTest";
String ACTION_RCV_MESSAGE = "com.jsouptest8.intent.action.MESSAGE";

public IntentServiceTest(){
    super("IntentServiceTest");
    Log.d(Tag, "IntentServiceTest constructor");
}

@Override
protected void onHandleIntent(Intent intent) {
    // TODO Auto-generated method stub
    Log.d(Tag, "in onHandleIntent");
    String url = intent.getStringExtra("URL");
    Document doc;
    int i=0;
    try{
      while(true){
         Log.d(Tag, "entered try block...");
         Log.d(Tag, "url = "+url);
         doc = Jsoup.connect(url)
         .get();

       Log.d(Tag, "past Jsoup.connect");
         Element data = doc.select("table").get(1).attr("bgcolor", "#f4f36f");
         Log.d(Tag, data.toString());
         Log.d(Tag, data.text());
         Log.d(Tag, "creating intent...");
         Intent broadcastIntent = new Intent();
         Log.d(Tag, "setting action...");
         broadcastIntent.setAction(ACTION_RCV_MESSAGE);
         broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
         broadcastIntent.putExtra("OUTPUT", data.toString());
         Log.d(Tag, "sending broadcast: "+(i++));
         sendBroadcast(broadcastIntent);
         Thread.sleep(30*1000);
      }
    }
    catch(StackOverflowError e){
        Log.d(Tag, "in StackOverflowError block...");
        Log.d(Tag, "creating intent...");
        Intent broadcastIntent = new Intent();
        Log.d(Tag, "setting action...");
        broadcastIntent.setAction(ACTION_RCV_MESSAGE);
        broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT);
        broadcastIntent.putExtra("OUTPUT", "系統忙線中, 請稍後再試");
        Log.d(Tag, "sending broadcast...");
        sendBroadcast(broadcastIntent);
    }
    catch(Exception e){
        Log.d(Tag, "in catch Exception block...");   
        onHandleIntent(intent);
    }
}

}

The problem is, I am stuck in this loop. Even if I kill the main activity and then return to it to enter a new input and the IntentService still returns based on the old input.

I need to know how I can update myself from the URL every 30 second without getting stuck. Thanks!

Answer

Ashwin picture Ashwin · Sep 25, 2012

An IntentService is meant to finish of a task and return. It does this task in a new thread. Do not use while loop in IntentService. Your IntentService will get killed after sometime. I am telling this from personal experience. I tried using a while loop in it. And at the end of the while loop I used sleep(60000) i.e 1 minute. But I found that my IntentService was killed after sometime.

I would recommend you not to use an AlarmManager for 30 seconds, as some have siggested. Because 30 seconds is too short. it will drain the battery. For AlarmManager use a minimum 1 minute with RTC.

If you still want it to be 30 seconds, use a service. In the service use your logic. But do that in a separate thread i.e spawn a new thread in your Service and used while loop there and sleep(). And do not forget to use startForeGround. This reduces the probabilty of android killing your service greatly.