2012-10-17 82 views
3

在我的首选项屏幕中,我想启动一项服务,以便在单击某个首选项时从Internet上下载文件。如果服务已经在运行(下载文件),那么服务应该停止(取消下载)。InDestroy onHandleIntent()仍然在onDestroy()后运行

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。它直接保存HttpURLConnectionFileOutputStream

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

回答

6

终于想出了如何让它工作。

正如我在我的问题中所述,不知何故onHandleIntent()将创建一个线程来完成这项工作。所以即使服务本身已经失效,线程仍然在运行。我通过添加一个全局变量来实现我的目标

private static boolean isStopped = false; 

DownloadService class。

为了抵消,而不是调用

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

我的服务,只需设置DownloadService.isStopped = true

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

希望这可以帮助遇到此问题的人。感谢您阅读这个问题的时间。

+3

为了隐藏这个'isStopped'变量,可以考虑在'onDestroy'中将其设置为true – xorgate

+0

isStopped变量必须是公共的。代码片段将其设置为私有。 – v01d

3

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

相关问题