在我的首选项屏幕中,我想启动一项服务,以便在单击其中一个首选项时从 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/