2014-03-06 38 views
3

我的意圖是在應用第一次運行時創建下載服務,並每24小時檢查一次更新。我原本一切都運行着我的主要活動,但似乎要在一個線程和一個類上運行一切。所以這是我的嘗試,將其轉移到另一個班級並投入使用。它假設在24小時內運行並檢查更新,如果在4小時內沒有互聯網再次嘗試。我特別想涉及任何遞歸問題,有兩個或三個相同的服務檢查更新,每24小時只有一個。但是將我的代碼整合到服務中有問題,我做錯了什麼?Android IntentService更新循環

public class DownloadService extends IntentService { 

// TODO 0 - Define your Download Service as Android component in 
// AndroidManifest.xml 
private int result = Activity.RESULT_CANCELED; 

public DownloadService() { 
    super("DownloadService"); 
} 

// Will be called asynchronously be Android 
@Override 
protected void onHandleIntent(Intent intent) { 

    private final Runnable mUpdateUi = new Runnable(){ 
     public void run(){ 
      check(); 
     } 

    }; 

    private void start(){ 
     new Thread(
      new Runnable(){ 
       public void run(){ 
        Log.d(TAG, "inside start"); 
        Looper.prepare(); 
        mHandler = new Handler(); 
        check(); 
        Looper.loop(); 
       } 
      } 
     ).run(); 
    } 


    private void check(){ 
     if (isNetworkAvailable()== true){ 
      try { 
       new checkupdate().execute(); 
       delayTime = 86400000; 
       Toast.makeText(DownloadService.this, "Daily update check!", Toast.LENGTH_SHORT).show(); 
      } 
      catch (IOException e) { 
       e.printStackTrace(); 
       delayTime = 21600000; 
      } 
     }else{ 
      delayTime = 21600000; 
      Toast.makeText(DownloadService.this, "No internet for Daily update check, try again in little!", Toast.LENGTH_SHORT).show(); 
     } 
     reCheck(); 
    } 

    private void reCheck(){ 
     mHandler.postDelayed(mUpdateUi, delayTime); 
    } 

} 

回答

2

IntentService已處理設置工作線程和隊列,並在隊列爲空時終止。這使得它成爲像下載服務那樣管理下載數據的實際工作的非常好的候選人,但對於時間調度程序來說並不是一個很好的候選人。

我建議使用AlarmManager來安排你的工作。你想要的是觸發一個意圖啓動你的下載服務,通過發送一個指示要做什麼的動作意圖。

還要注意的是,如果你想取消與行動的IntentService,你將需要實現onStartCommand除了通常的onHandleIntent,這樣您就可以立即行動迴應 - 你不能從onHandleIntent做到這一點,因爲在隊列中的當前任務完成之前,意圖不會被髮送到該目標。這裏有一個簡單的例子:

public class DownloadService extends IntentService { 

    private static final String TAG = "DownloadService"; 

    //////////////////////////////////////////////////////////////////////// 
    // Actions 

    public static final String ACTION_CANCEL = "package.name.DownloadService.action.CANCEL"; 
    public static final String ACTION_DOWNLOAD = "package.name.DownloadService.action.DOWNLOAD"; 

    //////////////////////////////////////////////////////////////////////// 
    // Broadcasts 

    public static final String BROADCAST_DOWNLOADED = "package.name.DownloadService.broadcast.DOWNLOADED"; 
    public static final String BROADCAST_ERROR  = "package.name.DownloadService.broadcast.ERROR"; 

    //////////////////////////////////////////////////////////////////////// 
    // Extras 

    public static final String MESSAGE = "package.name.DownloadService.extra.MESSAGE"; 
    // etc. 

    private boolean isCancelled; 

    // usual stuff omitted 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     if(intent != null) { 
      String action = intent.getAction(); 
      Log.v(TAG, "onStartCommand() - action: "+action); 
      if(ACTION_CANCEL.equals(action)) { 

       isCancelled = true; 

       // insert code here to signal any objects to cancel 
       // their work, etc. 

       stopSelf(); 
      } 
     } 

     return super.onStartCommand(intent, flags, startId); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     if(intent != null) { 
      final String action = intent.getAction(); 
      Log.v(TAG, "onHandleIntent() - action: "+action); 
      if(ACTION_DOWNLOAD.equals(action)) { 
       handleDownloading(intent); 
      } 
      else if(ACTION_CANCEL.equals(action)) { 
       // nothing to do here, handled in onStartCommand 
      } 
     } 
    } 

    //////////////////////////////////////////////////////////////////// 

    private void handleDownloading(Intent intent) { 

     // get stuff you need from the intent using intent.getStringExtra(), etc. 

     if(!isCancelled) { 
      // do downloading, call broadcastDownloaded() when done 
     } 
     else { 
      // stop work, send broadcast to report cancellation, etc. 
     } 
    } 

    // send a broadcast to a BroadcastReceiver (e.g. in your activity) 
    // to report that the download completed 
    private void broadcastDownloaded() { 
     Log.v(TAG, "broadcastDownloaded()"); 
     Intent broadcastIntent = new Intent(); 
     if (broadcastIntent != null) { 
      broadcastIntent.setAction(BROADCAST_DOWNLOADED); 
      broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
      sendBroadcast(broadcastIntent); 
     } 
    } 

    private void broadcastError(String message) { 
     Log.v(TAG, "broadcastError(), message: "+message); 
     Intent broadcastIntent = new Intent(); 
     if (broadcastIntent != null) { 
      broadcastIntent.setAction(BROADCAST_ERROR); 
      broadcastIntent.addCategory(Intent.CATEGORY_DEFAULT); 
      if(message != null) { 
       broadcastIntent.putExtra(MESSAGE, message); 
      } 
      sendBroadcast(broadcastIntent); 
     } 
    } 
} 
+0

這非常有趣,並感謝您的迴應!我目前正在將我的下載內容發送到下載管理器,那麼您還會使用意向服務的兄弟嗎?我無法廢除意圖服務的想法,只需使用警報管理器在24小時內觸發檢查更新,然後像往常一樣將下載文件發送到下載管理器? – MAXGEN

+0

如果你使用'android.app。DownloadManager'然後不,你不需要使用IntentService。關於使用自己的IntentService的唯一原因是在調用DownloadManager之前立即執行一些其他任務 - 因爲IntentService實現了一個工作隊列,所以它可以是鏈接任務的便捷方式。根據你所描述的內容,雖然在這種情況下我沒有看到任何需要。 DownloadManager已經以更健壯和靈活的方式做了你自定義的IntentService需要做的事情。 –

+0

「...除了通常的onHandleIntent之外,您還需要實現onStartCommand ...」 - 謝謝。我一直在努力更新我的'IntentService'行動。 –

0

這不是IntentService是如何使用的。根據documentation,IntentService已經創建了自己的工作線程。您不應該創建自己的:

客戶端通過startService(Intent)調用發送請求;該服務根據需要啓動,使用工作線程輪流處理每個Intent,並在其停止工作時自行停止。

除了事實如下所示不會編譯你的代碼(你start方法是onHandleIntent方法內),您的一般態度似乎開始自己的工作線程。這種方法會發生什麼,你會開始線程,onHandleIntent將完成,然後服務將被停止。除了實際上沒有工作,這種方法也是一個壞主意,因爲(最好如果你幸運的話)服務將連續24/7運行。

你應該做的是實際做你的主要工作onHandleIntent其中IntentService將排隊在你的工作線程。然後,使用postDelayed而不是使用AlarmManager來設置鬧鐘,以便在24小時或4小時內發送Intent以再次啓動服務。

+0

那麼我應該打電話給服務來做我的更新工作嗎?所以我在服務中運行這段代碼的目的是因爲我在與其他runnable或handler處理同一主線程時遇到問題。所以我現在不知道該怎麼辦?這是我原來的發帖。 https://stackoverflow.com/questions/22184419/android-delay-check-for-update-recursive/22184754?noredirect=1#22184754 – MAXGEN