2012-06-11 37 views
1

我必須每隔一秒在後臺運行一段代碼,代碼將調用一個web服務,該服務將搜索數據庫並將值返回給應用程序。我的問題是哪種方法最有效的做到這一點?我已經閱讀了定時器,線程,AsyncTask和服務,每個人似乎都有自己的優點和缺點。請有人告訴我哪個最適合考慮執行時間和電池壽命。在Android中每隔1秒鐘在後臺運行我的代碼

感謝

更新: 我決定用Aysnc任務,同時使用TimeTask觸發定期的到的AsyncTask在後臺運行我的代碼。這樣,當我離開該特定活動時,操作被破壞

+0

坦率地說,1秒似乎太短的Web服務+數據庫搜索。您是否測量了首次調用web服務和響應之間的時間?我會用Handler或Service給它一個鏡頭(取決於在應用程序完成時是否應該停止該後臺工作)。 – hovanessyan

+0

是的,它只會在特定活動中處於活動狀態,在該活動之外它應該被停用 – Amanni

+0

比我認爲看看@ Handler是明智的,因爲您可以輕鬆地將其綁定到活動生命週期。 – hovanessyan

回答

0

您將不得不創建新的Thread,以便在通話時間超出預期時通話不會鎖定設備。 AsyncTask是使用多線程的簡單方法,但缺少重複任務的功能。我會說你最好使用Timer或更新的ScheduledExecutorService。 如果您選擇使用Timer,那麼您將創建一個可供您使用的TimerTaskScheduledExecutorService取而代之的是一個Runnable。

您可能想要將線程包裝在Service(該服務不提供新線程),但根據您的需要,這並非總是必要的。

正如評論中所建議的那樣,您也可以使用Handler.postDelayed()。 (從Looper docs代碼)

class LooperThread extends Thread { 
     public Handler mHandler; 

     public void run() { 
      Looper.prepare(); 

      mHandler = new Handler() { 
       public void handleMessage(Message msg) { 
        // process incoming messages here 
       } 
      }; 

      Looper.loop(); 
     } 
    } 

也;:雖然你仍然需要創建一個新的線程,然後調用Looper.prepare()就可以了每秒對Web服務的調用似乎過於頻繁,特別是在用戶連接速度緩慢或需要傳輸數據的情況下,儘量減少調用。

+0

handler.postDelayed(...)的使用,而不是Java的經典計時器是由Android開發團隊建議的。此外,我同意你說,每1秒調用一次網絡服務是電池消耗的地獄:D –

+0

@GökhanBarışAker:是的,但處理程序在創建它們的線程上運行(它也必須有Looper),所以他仍然會創建一個新線程,然後調用Looper.prepare()。 – Jave

+0

@GökhanBarışAker在我的帖子中添加了Handler方法:) – Jave

2

對於像這樣的操作,我傾向於使用Service組件。對於任務本身,我使用一個AsyncTask,它會在重複自身之前等待一段時間(使用while循環)。

+0

聽起來像一個有趣的方式來做到這一點,但在這種方法是有無論如何返回值給應用程序? – Amanni

+0

您應該可以調用嵌套任務的類中的方法。這樣,您可以將數據從asyncTask獲取到服務組件。我通過使用廣播接收器將我的數據傳遞給我的活動 – Wottah

0

我認爲這不僅是一種解決方案,所以取決於您。您可以嘗試啓動線程與此運行方式:

private final int spleeptime = 1000; 
public boolean running; 

@Override 
public void run() { 
    while (running) { 
     try { 
      int waited = 0; 
      while ((waited < spleeptime)) { 
       sleep(100); 
       waited += 100; 
      } 
     } catch (InterruptedException e) { 
     } finally { 
      // your code here 
     } 
    } 
} 
3

你應該用服務做後臺操作,但在你的情況,你要在這裏1秒運行的代碼是使用處理器中調用它的服務的例子每1秒。

public class YourService extends Service { 
private static final String TAG = "Your Service"; 
private final Handler handler = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 

} 
}; 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
public void onCreate() { 
// Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show(); 
    Log.d(TAG, "onCreate"); 

} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
// Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show(); 
    handler.removeCallbacks(sendUpdatesToUI); 
} 
private Runnable sendUpdatesToUI = new Runnable() { 
     public void run() { 
      /// Any thing you want to do put the code here like web service procees it will run in ever 1 second 
      handler.postDelayed(this, 1000); // 1 seconds 
     } 
}; 
@Override 
public void onStart(Intent intent, int startid) { 

    handler.removeCallbacks(sendUpdatesToUI); 
    handler.postDelayed(sendUpdatesToUI, 1000);//1 second  
    Log.d(TAG, "onStart"); 
} 

} 

和服務不能每次運行的Android在3或4小時我建議你使用前臺服務使用過程中長時間運行的閒置服務。

+0

服務可以從一個活動中啓動和停止?它也可以返回一個值給應用程序? – Amanni

+0

是的,你可以stopService(新的Intent(context,yourService.class)); \t \t startService(new Intent(context,yourService.class)); –

+0

如果你服務的話,UI有可能會凍結 – krisDrOid

相關問題