在onDestroy()触发后,IntentService onHandleIntent()仍在运行

时间:2012-10-17 04:48:27

标签: android android-service intentservice

在我的首选项屏幕中,我想启动一项服务,以便在点击其中一个首选项时从互联网上下载文件。如果服务已在运行(下载文件),则应停止服务(取消下载)。

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

服务类:

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

此服务将在下载完成之前运行。函数downloadFiles()不使用AsyncTask。它会HttpURLConnection直接保存FileOutputStream

单击首选项时,服务正确启动。现在的问题是,当我点击停止使用stopService()的服务时,DownloadService会立即触发onDestroy();但是根据日志,onHandleIntent()仍在运行,因为我仍然可以连续看到HTTP请求。这是因为Service在一个线程中运行,还是我做错了什么?当onHandleIntent()被调用时,如何确保stopService()中的所有内容立即停止(或至少能够停止)?

2 个答案:

答案 0 :(得分:8)

最后想出了如何让它发挥作用。

正如我在我的问题中所述,onHandleIntent()不知何故会创建一个线程来完成这项工作。因此,即使服务本身被破坏,该线程仍在运行。我通过添加全局变量

实现了我的目标
private static boolean isStopped = false;

DownloadService课程。

要取消我的服务,而不是打电话

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

只需设置DownloadService.isStopped = true

最后,在onHandleIntent()中执行操作时,请定期检查此布尔值以查看是否应该停止下载。如果isStopped = true,立即返回,服务将自行停止。

希望这也有助于遇到此问题的人。感谢您抽出时间阅读这个问题。

答案 1 :(得分:4)

它有一个单独的线程来完成工作,并且根据它正在做什么,可能无法立即停止它。如果它在I / O上阻塞,则中断它可能不起作用。