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();
    }
}