我的应用程序中有一个服务,我将请求发送到服务器。在我发送请求以在服务器上启动操作之后,我需要每隔15秒发送一次请求以跟踪进度,从而轮询服务器以获取更新。为此,我使用调用Runnable的ScheduledExecutorService。
服务在onHandleIntent
中执行大量操作,然后启动执行轮询的ScheduledExecutorService。所有这一切都很好。
问题是当ScheduledExecutorService每隔一段时间执行Runnable时,服务就会被破坏,就像调用onDestroy方法一样。有没有办法防止这种情况发生?
我在服务中注册了一个广播接收器,当ScheduledExecutorService执行Runnable时,用户可以随时触发该广播接收器。 但是,由于服务被销毁,接收方未注册。
以下是一些简化的代码:
@Override
protected void onHandleIntent(Intent intent) {
Log.d(TAG, "OnHandleIntent started");
try {
if (intent != null) {
final String action = intent.getAction();
if (getActionUpload().equals(action)) {
wakeLock.acquire();
notificationConfig = new CustomNotificationConfig();
//Register receiver to stop operation
IntentFilter filter = new IntentFilter(ThirdPartyStopReceiver.ACTION_STOP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
mThirdPartyStopReceiver = new ThirdPartyStopReceiver();
registerReceiver(mThirdPartyStopReceiver, filter);
Boolean operationStarted = startOperation();
if (operationStarted) {
checkProgressAtIntervals();
}
}
}
} catch (Exception e) {
Log.e(TAG, "Error with XML");
e.printStackTrace();
} finally {
wakeLock.release();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
try {
//Unregister the receiver
unregisterReceiver(mThirdPartyStopReceiver);
} catch (IllegalArgumentException e) {
//Receiver has already been unregistered. Do nothing
e.printStackTrace();
}
}
private void checkProgressAtIntervals() {
Log.d(TAG,"in checkProgressAtIntervals");
final ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
try {
int progress = sendProgressRequest();
if(isCanceled){
sendCancelRequest();
ses.shutdown(); //Stop polling
}
if (progress >= 100) {
ses.shutdown(); //Stop polling
}
} catch (Exception e) {
Log.e(TAG, "Exception in sendProgressRequest ");
e.printStackTrace();
}
}
}, 1, 15, TimeUnit.SECONDS);
}
public class ThirdPartyStopReceiver extends BroadcastReceiver {
public static final String ACTION_STOP = "thirdpartystop";
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Cancel request received in onReceive");
isCanceled = true;
//...
}
}
正如您所看到的,如果收到“停止”广播,我需要在服务中执行一些代码。
我尝试使用Handler及其postDelayed
方法,但在Handler开始执行之前服务被销毁,因此Runnable永远不会执行。我尝试使用Looper.myLooper()
实例化处理程序,但结果相同。
由于runnable包含HTTP调用,因此使用Looper.getMainLooper()
实例化Handler会抛出NetworkOnMainThreadException
答案 0 :(得分:1)
您似乎正在使用IntentService
,它在结束工作后停止,即onHandleIntent
方法。 IntentService
意图是短暂的。
尝试使用常规Service
代替。请注意,Android可以自行决定停止服务,但一般来说,服务将会运行很长时间。