7

我的 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 秒从 URL 更新一次而不会卡住。谢谢!

4

4 回答 4

7

AnIntentService意味着完成一项任务并返回。它在一个新线程中执行此任务。不要在 IntentService 中使用 while 循环。你IntentService会在一段时间后被杀死。我是从个人经验告诉这个的。我尝试在其中使用while循环。在 while 循环结束时,我使用了sleep(60000)1 分钟。但是我发现我的 IntentService 在一段时间后被杀死了。

我建议您不要在 30 秒内使用 AlarmManager,因为有些人已经表明了这一点。因为30秒太短了。它会耗尽电池。对于 AlarmManager 使用RTC至少 1 分钟。

如果您仍然希望它是 30 秒,请使用服务。在服务中使用您的逻辑。但是在一个单独的线程中执行此操作,即在您的服务中生成一个新线程并在那里使用 while 循环和sleep(). 并且不要忘记使用startForeGround。这大大降低了 android 杀死你的服务的概率。

于 2012-09-25T12:30:51.563 回答
2

在 IntentService 或任何类型的服务中使用 while 语句是个坏主意。在 IntentService 内部尤其是一个坏主意,因为 IntentService 应该完成一项任务然后自动终止,这实际上违背了使用 IntentService 的全部目的。

我建议删除 IntentService 中的循环,并使用警报每 30 秒唤醒一次 IntentService。这样,您的服务肯定会每 30 秒被调用一次,并且在它未处理的时间内,它实际上可以重新进入睡眠状态。此外,要处理在 IntentService 为旧请求提供服务时收到对 IntentService 的新调用的情况,您可以将代码添加到 IntentService 的 onStartCommand 方法,以查看该调用是应该排队处理还是完全忽略。

使用此方法设置警报:

public void setRepeating(int类型,长triggerAtMillis,长intervalMillis,PendingIntent操作)

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

要获得更有效的方法,请使用 setInexactRepeating (但这不能保证 30 秒唤醒)

PS。我们通常不会覆盖 IntentService 的 onStartCommand,但如果您的应用程序确实具有该功能,则可以这样做。

于 2012-08-18T09:21:38.093 回答
1

在此链接中,您将找到一项使用计时器进行自我更新的服务

保持服务运行

如果您对 while 循环感到满意,只需编写一个存在循环的 if 语句

if(thisIsTrue)
 {
   break; // this will exit the loop!
 }
于 2012-08-18T07:24:16.340 回答
0

最好将循环或计时器或任何此类正在运行的任务保留在MainActivity自身中并每次都执行 IntentService。因为IntentService每次都会执行任务并完成自己或queue进一步交付的任务。

从文档 -

IntentService 将接收 Intent,启动工作线程,并酌情停止服务。

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

于 2012-08-18T07:35:08.470 回答