【问题标题】:IntentService using ThreadPoolExecutor... recommended or not?IntentService 使用 ThreadPoolExecutor... 推荐与否?
【发布时间】:2012-08-23 15:30:21
【问题描述】:

我正在设计一个 android 应用程序,它将监听传入的 SMS 并以特定方式处理它们。 我有一个接收消息并将其发送到意图服务的广播接收器:

Intent serviceIntent = new Intent(context, SMSIntentService.class);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);

intent 服务的目的是将 SMS 保存到我自己的数据库中,然后通过 HTTP POST 将该消息发送到服务器,评估结果并更新应用程序的数据库并最终回复发送者。 到目前为止一切都很好,但是由于有可能同时有很多 SMS 到达,我想将与服务器的通信解耦,将其放在另一个线程中。

所以到目前为止我正在做的是:

SmsDto sms = smsDataSource.saveSms(new SmsDto(originator, body, timestamp));

SMSProcessingTask task = new SMSProcessingTask(this.getApplicationContext(), sms);
Thread t = new Thread(task);
t.start();

到目前为止一切都很好,但我不相信这种包含大量消息的实现。

所以,我的问题是:

在意图服务中,是否建议使用 ThreadPoolExecutor? 我最终会得到这样的结果:

//in IntentService's onCreate
this.executor = Executors.newCachedThreadPool();

//in onHandleIntent()
executor.execute(task);

如果一段时间内没有收到消息并且 IntentService 停止会发生什么情况。它创建的线程会继续运行吗?

我不知道这种方法是否是处理我想要完成的事情的最佳方式。

谢谢

更新:

  • 此应用中根本没有 UI 活动。
  • 由于与服务器的通信可能需要相当长的时间,我想尽量减少消息的处理时间,以便快速提取队列中的下一条短信并开始处理。

【问题讨论】:

    标签: android broadcastreceiver intentservice executors


    【解决方案1】:

    不,你不应该使用一个。主要原因是 SQlite 访问不是线程安全的,因此您不希望多个线程同时写入数据库。 此外,如果您的任务碰巧更新了 UI,它也不会那样工作。

    我真的不明白您为什么要执行这些任务:IntentService 已经从 UI 线程处理了它的消息。

    【讨论】:

    • 我在这里读到,如果对 SQLlite DB 的访问是单例的,那么它是线程安全的。此外,我不会更新相同的消息。 IntentService 有一个队列,如果一条消息由于某种原因需要 n 秒来处理,则在这 n 秒之后将开始处理下一行。这就是我要避免的。
    【解决方案2】:

    你可以做的是使用 submit(Callable) 方法而不是 execute 方法。

    这样你就可以得到一个未来的对象,其中包含你想在数据库中写入的数据,并且没有线程会真正接触它,因为它不像 Phillippe 所说的那样安全

    当我需要发送多个 httprquests 时,我以类似的方式使用它。 我使用 SQL DB 管理它们,所以写入只发生在 onHandleIntent 上。

    while(helper.requestsExists()){
            ArrayList<String> requestArr = helper.getRequestsToExcute(3);
            //checks if the DB requests exists
            if(!requestArr.isEmpty()){
                //execute them and delete the DB entry
                for(int i=0;i<requestArr.size();i++){
                    file = new File(requestArr.get(i));
                    Log.e("file",file.toString());
                    Future<String> future = executor.submit(new MyThread(file,getApplicationContext()));
    
                    Log.e("future object", future.toString());
                    try {
                        long idToDelete = Long.parseLong(future.get());
                        Log.e("THREAD ANSWER", future.get() + "");
                        helper.deleteRequest(idToDelete);
                    } catch (InterruptedException e) {
                        Log.e("future try", "");
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        executor.shutdown();
    

    其次,在 onHandleIntent 完成之前,intentService 不会停止,即使这样,线程也会继续运行,直到完成工作

    【讨论】:

      猜你喜欢
      • 2016-07-08
      • 2011-06-22
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 2021-08-16
      • 1970-01-01
      相关资源
      最近更新 更多