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

标签 android android-service intentservice

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

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。它直接用 FileOutputStream 保存 HttpURLConnection

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

最佳答案

终于想出了如何让它发挥作用。

正如我在问题中所述,onHandleIntent() 会以某种方式创建一个线程来完成这项工作。所以即使服务本身被销毁,线程仍然在运行。我通过添加一个全局变量实现了我的目标

private static boolean isStopped = false;

DownloadService 类。

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

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

只需设置 DownloadService.isStopped = true

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

希望这对遇到此问题的人也有帮助。感谢您花时间阅读这个问题。

关于android - IntentService onHandleIntent() 在 onDestroy() 触发后仍在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12927307/

相关文章:

java - 从静态方法更改非静态值

android - android studio NDK 上的 turbo c++ graphics.h 程序

android - 如何让 Android Service 与 Activity 通信

android - Intent 服务启动后防止更改应用程序呈现 Android 的顺序

java - 当我们退格删除最后一个字符时,TextWatcher 覆盖不会被调用。我如何知道最后一个字符是否被删除?

android - 如何在运行时以编程方式使用 xml 中的维度设置文本大小?

android 广播接收器(收到调用和短信)在 android nougat 中无法工作

android - 为未决 Intent 设置可变性标志但仍收到 IllegalArgumentException 错误

android - progressDialog 不在 onReceive 中关闭

android - 即使在 onHandleIntent 完成后 IntentService 仍在后台运行