2012-10-17 59 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,則中斷它可能不起作用。

相關問題