我正在设计一个android应用程序,它将监听传入的短信,并以特定的方式处理它们。我有一个广播接收器,它接收消息并将其发送到意向服务:
Intent serviceIntent = new Intent(context, SMSIntentService.class);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);
意向服务的目的是将短信保存到我自己的数据库中,然后通过HTTPPOST将该消息发送到服务器,评估结果并更新应用程序的数据库,最终回复发件人。到目前为止,一切都很好,但由于有可能会有很多短信同时到达,我想将与服务器的通信解耦,并将其放入另一个线程。
到目前为止,我正在做的是:
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活动
- 由于与服务器的通信可能需要相当长的时间,我想最大限度地减少消息的处理时间,这样队列中的下一条短信就会被快速接收并开始处理
Ni
不,您不应该使用。主要原因是SQlite访问不是线程安全的,所以您不希望多个线程同时写入数据库。此外,如果您的任务碰巧更新了UI,它就不会以这种方式工作。
我真的不明白为什么你有这些任务:IntentService已经在UI线程外处理了它的消息。
您可以使用submit(Callable)方法而不是execute方法。
这样,你就可以获得一个未来的对象,其中包含你想写入数据库的数据,并且没有线程会像Phillippe所说的那样实际接触它,因为它不安全
当我需要发送多个httprquest时,我以类似的方式使用它。我使用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完成之前,intetService不会停止,即使这样,线程也会继续运行,直到它们完成了自己的工作