StopService onDestroy 被调用但服务未结束
StopService onDestroy being called but service not ending
我尝试使用 TimerTask 从服务器下载数据 api,任务在后台应用程序中循环。
我有服务class:
public class RequestNewInvoice extends Service {
private Timer timer;
private CheckTask checkTask;
private Handler handler;
private JSONParser jsonParser;
private JSONObject jsonObject;
private boolean startService = true;
private void init(){
this.handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e("Message: ",msg.obj+"");
return false;
}
});
this.timer = new Timer();
this.checkTask = new CheckTask();
this.startService = true;
timer.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, int flags, final int startId) {
init();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
}
private class CheckTask extends TimerTask{
@Override
public void run() {
funcCheckInvoice();
}
}
public void funcCheckInvoice(){
try{
if(startService){
Log.e("SERVICE START", "true");
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
httpClient = new DefaultHttpClient(httpParameters);
HttpGet httpGet = new HttpGet(SuperVAR.URL_GET_LIST_INVOICE_IN_CURRENT_SHIPMENT+"?"+ URLEncodedUtils.format(_REQUEST, "utf-8")+"unused="+System.currentTimeMillis()/1000);
httpGet.setHeader("token",token);
httpGet.setHeader("Cache-Control","no-cache");
httpGet.setHeader("Cache-Control","no-store");
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
jsonObject = jsonParser.getJSONFromRESPONSE(httpEntity);
if(jsonObject == null){
Message message = Message.obtain();
message.obj = "get null.... internet like shit T_T";
handler.sendMessage(message);
}else {
Message message = Message.obtain();
message.obj = "download ok";
handler.sendMessage(message);
}
}else {
Log.e("SERVICE START", "false");
return;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
当我运行在ActivityClass中停止服务时,服务调用了onDestroy函数,但定时器仍然存在。
如何销毁定时任务?
您已经以 START_STICKY 的身份启动了您的服务,这可能就是为什么
你不能停止服务。
下面是START_STICKY的definition。
Constant to return from onStartCommand(Intent, int, int): if this
service's process is killed while it is started (after returning from
onStartCommand(Intent, int, int)), then leave it in the started state
but don't retain this delivered intent. Later the system will try to
re-create the service. Because it is in the started state, it will
guarantee to call onStartCommand(Intent, int, int) after creating the
new service instance; if there are not any pending start commands to
be delivered to the service, it will be called with a null intent
object, so you must take care to check for this.
This mode makes sense for things that will be explicitly started and
stopped to run for arbitrary periods of time, such as a service
performing background music playback.
尝试使用 START_NOT_STICKY
您还需要在调用时更改调用取消的方式
scheduleAtFixedRate.
private ScheduledThreadPoolExecutor scheduleTaskExecutor;
private ScheduledFuture schedule;
...
scheduleTaskExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(5);
schedule = scheduleTaskExecutor.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
@Override
public void onDestroy()
{
super.onDestroy();
startService = false;
checkTask.cancel();
schedule.cancel(true);
}
使用 Handler 并在销毁时移除回调任务
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
scanTask = new TimerTask() {
public void run() {
handler.post(task);
}};
t.schedule(scanTask, 5000, 20 * 1000);
Runnable task = new Runnable() {
@Override
public void run() {
//START YOUR JOB
(new FetchData()).execute();
}
};
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
handler.removeCallbacks(task);
}
public class FetchData extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
funcCheckInvoice();
}
}
我尝试使用 TimerTask 从服务器下载数据 api,任务在后台应用程序中循环。
我有服务class:
public class RequestNewInvoice extends Service {
private Timer timer;
private CheckTask checkTask;
private Handler handler;
private JSONParser jsonParser;
private JSONObject jsonObject;
private boolean startService = true;
private void init(){
this.handler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e("Message: ",msg.obj+"");
return false;
}
});
this.timer = new Timer();
this.checkTask = new CheckTask();
this.startService = true;
timer.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, int flags, final int startId) {
init();
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
}
private class CheckTask extends TimerTask{
@Override
public void run() {
funcCheckInvoice();
}
}
public void funcCheckInvoice(){
try{
if(startService){
Log.e("SERVICE START", "true");
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
HttpConnectionParams.setSoTimeout(httpParameters, SuperVAR.GET_CURRENT_SHIPMENT_TIMEOUT);
httpClient = new DefaultHttpClient(httpParameters);
HttpGet httpGet = new HttpGet(SuperVAR.URL_GET_LIST_INVOICE_IN_CURRENT_SHIPMENT+"?"+ URLEncodedUtils.format(_REQUEST, "utf-8")+"unused="+System.currentTimeMillis()/1000);
httpGet.setHeader("token",token);
httpGet.setHeader("Cache-Control","no-cache");
httpGet.setHeader("Cache-Control","no-store");
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
jsonObject = jsonParser.getJSONFromRESPONSE(httpEntity);
if(jsonObject == null){
Message message = Message.obtain();
message.obj = "get null.... internet like shit T_T";
handler.sendMessage(message);
}else {
Message message = Message.obtain();
message.obj = "download ok";
handler.sendMessage(message);
}
}else {
Log.e("SERVICE START", "false");
return;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
当我运行在ActivityClass中停止服务时,服务调用了onDestroy函数,但定时器仍然存在。
如何销毁定时任务?
您已经以 START_STICKY 的身份启动了您的服务,这可能就是为什么 你不能停止服务。
下面是START_STICKY的definition。
Constant to return from onStartCommand(Intent, int, int): if this service's process is killed while it is started (after returning from onStartCommand(Intent, int, int)), then leave it in the started state but don't retain this delivered intent. Later the system will try to re-create the service. Because it is in the started state, it will guarantee to call onStartCommand(Intent, int, int) after creating the new service instance; if there are not any pending start commands to be delivered to the service, it will be called with a null intent object, so you must take care to check for this.
This mode makes sense for things that will be explicitly started and stopped to run for arbitrary periods of time, such as a service performing background music playback.
尝试使用 START_NOT_STICKY
您还需要在调用时更改调用取消的方式 scheduleAtFixedRate.
private ScheduledThreadPoolExecutor scheduleTaskExecutor;
private ScheduledFuture schedule;
...
scheduleTaskExecutor = (ScheduledThreadPoolExecutor) Executors.newScheduledThreadPool(5);
schedule = scheduleTaskExecutor.scheduleAtFixedRate(checkTask, 5000, 20 * 1000);
@Override
public void onDestroy()
{
super.onDestroy();
startService = false;
checkTask.cancel();
schedule.cancel(true);
}
使用 Handler 并在销毁时移除回调任务
TimerTask scanTask;
final Handler handler = new Handler();
Timer t = new Timer();
scanTask = new TimerTask() {
public void run() {
handler.post(task);
}};
t.schedule(scanTask, 5000, 20 * 1000);
Runnable task = new Runnable() {
@Override
public void run() {
//START YOUR JOB
(new FetchData()).execute();
}
};
@Override
public void onDestroy() {
super.onDestroy();
Log.e("SERVICE STOP", "true");
startService = false;
checkTask.cancel();
timer.cancel();
timer.purge();
handler.removeCallbacks(task);
}
public class FetchData extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
funcCheckInvoice();
}
}