IntentService onHandleIntent() still running after onDestroy() fired

筅森魡賤 提交于 2019-12-12 09:48:01

问题


In my preference screen, I want to start a service to download files from the internet when one of the preference is being clicked. If the service is already running (downloading files), then the service should be stopped (cancel download).

public class Setting extends PreferenceActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    downloadPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {

        @Override
        public boolean onPreferenceClick(Preference pref) {
            if (DownloadService.isRunning) {
                Setting.this.stopService(new Intent(Setting.this,
                    DownloadService.class));
            } else {
                Setting.this.startService(new Intent(Setting.this,
                    DownloadService.class));
            }
            return false;
        }
    });
    }
}

The service class:

public class DownloadService extends IntentService {

public static final int DOWNLOAD_SUCCESS = 0;
public static final int DOWNLOAD_FAIL = 1;
public static final int DOWNLOAD_CANCELLED = 2;
public static final int SERVER_FAIL = 3;

public static boolean isRunning = false;
private int result;

public DownloadService() {
    super("DownloadService");
}

@Override
public void onCreate() {
    super.onCreate();
    isRunning = true;
}

@Override
protected void onHandleIntent(Intent intent) {
    if (NetworkStateUtils.isInternetConnected(getApplicationContext())) 
        result = downloadFiles(getApplicationContext());

}

@Override
public void onDestroy() {
    super.onDestroy();
    switch (result) {
    case DOWNLOAD_SUCCESS:
        Toast.makeText(getApplicationContext(), R.string.download_finished,
                Toast.LENGTH_SHORT).show();
        break;
    case DOWNLOAD_CANCELLED:
        Toast.makeText(getApplicationContext(), R.string.download_canceled,
                Toast.LENGTH_SHORT).show();
        break;
    case DOWNLOAD_FAIL:
        Toast.makeText(getApplicationContext(), R.string.download_failed,
                Toast.LENGTH_SHORT).show();
        break;
    }
    isRunning = false;
}
}

This service is meant to run until download has finished. The function downloadFiles() uses no AsyncTask. It saves the HttpURLConnection with an FileOutputStream directly.

The service started correctly when I click the preference. Now the problem is, when I click to stop the service with stopService(), DownloadService triggered onDestroy() immediately; however according to logs, onHandleIntent() is still running becasue I can still see HTTP requests continuously. Is this because Service runs in a thread itself, or am I doing something wrong? How can I ensure that everything in onHandleIntent() stops immediately (or at least able to stop) when stopService() is being called?


回答1:


Finally figured out how to make it work.

As I stated in my question, somehow onHandleIntent() will create a thread to do the job. So even when the service itself is destoryed, the thread is still running. I achieved my goal by adding a global variable

private static boolean isStopped = false;

to DownloadService class.

In order to cancel my service, instead of calling

Setting.this.stopService(new Intent(Setting.this, DownloadService.class));

just set DownloadService.isStopped = true.

Finally, while doing things in onHandleIntent(), check this boolean periodically to see if it should stop downloading. If isStopped = true, return immediately and the service will stop itself.

Hope this helps someone who come across this problem too. And thanks for your time reading this question.




回答2:


It has a separate thread to do work, and depending on what it is doing it might not be possible to stop it immediately. If it is blocking on I/O, interrupting it will likely have no effect.



来源:https://stackoverflow.com/questions/12927307/intentservice-onhandleintent-still-running-after-ondestroy-fired

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!