3

在我的首选项屏幕中,我想在单击其中一个首选项时启动一项服务以从 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()使用 no AsyncTask。它直接HttpURLConnection用 a保存FileOutputStream

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

4

2 回答 2

8

终于知道如何让它工作了。

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

private static boolean isStopped = false;

DownloadService上课。

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

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

刚刚设置DownloadService.isStopped = true

最后,在做事的时候onHandleIntent(),定期检查这个布尔值,看看它是否应该停止下载。如果isStopped = true,立即返回,服务将自行停止。

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

于 2012-10-18T02:44:38.027 回答
4

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

于 2012-10-17T05:15:40.800 回答