我正在设计一个Android应用程序,它将收听传入的短信并以特定方式处理它们。 我有一个广播接收器接收消息并将其发送到意向服务:
Intent serviceIntent = new Intent(context, SMSIntentService.class);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);
意图服务的目的是将SMS保存到我自己的数据库,然后通过HTTP POST将该消息发送到服务器,评估结果并更新应用程序的数据库并最终回复发件人。 到目前为止一切都很好,但由于很多短信可能同时到达,我想将与服务器的通信分离到另一个线程中。
所以我到目前为止所做的是:
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停止,会发生什么。它创建的线程是否会继续运行?
我不知道这种方法是否是处理我想要完成的事情的最佳方法。
由于
更新
的Ni
答案 0 :(得分:0)
不,你不应该使用它。主要原因是SQlite访问不是线程安全的,因此您不希望多个线程同时写入数据库。 此外,如果你的任务碰巧更新了UI,那就不会那样了。
我真的不明白为什么你有这些任务:IntentService已经从UI线程处理它的消息。
答案 1 :(得分:0)
您可以使用提交(可调用)方法而不是执行方法。
通过这种方式你可以获得一个未来的对象,你想要在数据库中写入数据,没有任何线程实际会触及它,因为它不像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不会停止,即使这样,线程也会继续运行直到他们完成工作