环路IntentService(loop in IntentService)

2019-09-21 08:33发布

我有一个无限循环中我IntentService来更新我的观点基于从主活动的输入每30秒一次。

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);
    }
}

}

问题是,我陷在这个循环。 即使我杀的主要活动,然后返回到它进入一个新的输入和IntentService仍返回基于旧的输入。

我需要知道我可以从网址更新自己以每30秒没有得到坚持。 谢谢!

Answer 1:

一个IntentService是为了任务和返回的完成。 它在一个新线程的任务。 不要在IntentService使用while循环。 你IntentService将一段时间后会被杀掉。 我从个人的经验告诉这一点。 我试图在它使用while循环。 并且在while循环我用的端部sleep(60000)即1分钟。 但是,我发现,我的IntentService在一段时间后杀死。

我建议你不要使用AlarmManager 30秒,如一些人所siggested。 因为30秒太短。 它会耗尽电池。 对于AlarmManager使用最少1分钟, RTC 。

如果您仍然希望它为30秒,使用服务。 在服务中使用你的逻辑。 但这样做,在一个单独的线程,即产卵在服务一个新的线程和使用while循环,并有sleep() 而且不要忘记使用startForeGround 。 这减少了机器人大大杀死你的服务的probabilty。



Answer 2:

使用IntentService内while语句,或与此有关的任何一种服务的是一个坏主意。 这是尤其是IntentService内一个坏主意,因为IntentService应该完成一个任务,然后获得自动终止,你在本质上击败使用IntentService的全部目的。

我会建议以去除IntentService循环和使用闹钟唤醒IntentService每30秒。 这样一来,你的服务被调用每30秒肯定和它不处理,它实际上可以回去睡觉的时间。 此外,为了处理这种情况,而IntentService所服务的较旧的请求被接收到IntentService新呼叫的情况下,您可以将代码添加到您的IntentService的onStartCommand方法,看看是否应将呼叫队列中等待处理或完全忽略。

使用此方法设置的报警:

公共无效setRepeating(整型,长triggerAtMillis,长intervalMillis,的PendingIntent操作)

链接: http://goo.gl/E9e6

为了更有效的方法,使用setInexactRepeating(但并不保证30秒唤醒)

PS。 我们通常不会覆盖的IntentService的onStartCommand但它可以,如果你的应用程序确实该功能来完成。



Answer 3:

在这个环节上,你会发现,使用定时器更新本身就是一种服务

保持服务运行

如果您舒适的while循环只写存在循环的if语句

if(thisIsTrue)
 {
   break; // this will exit the loop!
 }


Answer 4:

这将是更好的,你保持环路或定时器或任何这样运行的任务在MainActivity本身和执行IntentService每次。 因为IntentService将执行任务,每次完成本身或queue的任务进一步传递。

从文件-

IntentService将获得意图,启动一个工作线程,并停止该服务为适当。

它使用work queue processor模式来维持的任务。



文章来源: loop in IntentService