2012-04-27 103 views
6

我有一個更新數據庫操作,它有一個活動,它不斷更新百分比,並在AsyncTask中運行。在後臺工作時更新UI

doInBackground()我調用控制器來更新數據庫並不斷更新活動的百分比,但是,如果我按Home按鈕或Back按鈕,操作將被取消。你建議我做什麼?

我試圖在doInBackground()裏面啓動一個服務,所以它會在後臺運行,但看起來它不工作。

我的代碼如下所示:

public class UpdateDatabaseAsyncTask extends AsyncTask<Void, Integer, Integer> 
{ 
    @Override 
    public void onPreExecute() 
    { 
     mCustomProgressBar.startAnimation(); 
    } 

    @Override 
    public Integer doInBackground(Void... params) 
    { 
     return mController.updateDatabase(); 
    } 

    @Override 
    public void onPostExecute(Integer result) 
    { 
     mCustomProgressBar.stopAnimation(); 
     // finish the activity 
    } 

    @Override 
    public void onProgressUpdate(Integer... value) 
    { 
     updatePercentageValue(value[0]); 
    } 

    public void callPublishProgress(Integer value) 
    { 
     publishProgress(value); 
    } 
} 

而且控制器內我調用該方法callPublishProgress(value)傳遞當前的百分比值,所以它會在UI publishProgress(value)

我在調試,我按下了home/back按鈕,它只是停止運行工作線程。


另一種解決辦法我試過了,已開始服務在後臺運行,無論用戶按home /後退按鈕或沒有,所以我想和服務將使到執行的控制方法的調用工作,它會調用callPublishProgress(value)來更新UI上的百分比值。

然而,發生了什麼事,代碼達到doInBackground()並啓動該服務,但它會立即轉到onPostExecute(),它只是沒等服務來完成(當然)。所以它給出了NullPointerException。我想在doInBackground()內設置一個循環,並在服務中設置了一個標誌,所以當服務尚未完成時(我正在使用IntentService)它將離開此循環,但它無法工作。

我也想過使用定時器。但我不知道。

我正在閱讀有關線程等文檔的文章,並建議使用AsyncTask,就像我正在嘗試做的一樣。它也談到了runOnUiThread(Runnable)

無論如何,我需要的是在後臺進行操作(可能使用IntentService),所以無論用戶按home鍵,它都會繼續運行,但它必須更新UI的百分比,並且當用戶離開屏幕並返回時,它會顯示屏幕中更新的當前百分比值。

我的情況最好的解決方案是什麼?

謝謝。

+0

請參閱SDK樣品中的API演示,有其計數並通知服務的例子一個可以顯示計數的前臺活動。 – 2012-04-27 17:20:31

+0

這個樣本的名稱是什麼? – rogcg 2012-04-27 17:26:28

+0

我不記得確切地說,它全部在sdk的samples /目錄中的API demos應用程序中 - 構建完整的東西來運行它並查看菜單並瀏覽代碼。其中很多其他有用的東西也值得了解。 – 2012-04-27 17:36:53

回答

3
public class MyServce extends Service{ 
public static final String BROADCAST_ACTION = "com.myapp"; 
Intent intent; 
private final Handler handler = new Handler(); 

@Override 
public void onCreate() 
{ 
    super.onCreate(); 
    intent = new Intent(BROADCAST_ACTION); 
} 

@Override 
    public void onStart(Intent intent, int startId) { 
     handler.removeCallbacks(sendUpdatesToUI); 
     handler.postDelayed(sendUpdatesToUI, 1000); // 1 second 

    } 
    private Runnable sendUpdatesToUI = new Runnable() { 
     public void run() { 
      DoYourWorking();   
      handler.postDelayed(this, 1000); // 1 seconds 
     } 

     private void DoYourWorking() { 
     ........ 
        ........ 
        intent.putExtra("key", progress); 
      sendBroadcast(intent); 

     } 
    }; 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    return null; 
} 
@Override 
public void onDestroy() { 
    super.onDestroy(); 
    handler.removeCallbacks(sendUpdatesToUI);  

} 
在活動註冊廣播

我們服務

private BroadcastReceiver brodcast = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
       //intent.getWhatever 
     // update your progress 
     //progressbar.setProgress 
    } 

寄存器廣播

registerReceiver(brodcast, new IntentFilter(MyService.BROADCAST_ACTION)); 
+0

工程就像一個魅力,但我不需要使用處理程序。我剛啓動了IntentService,並從IntentService中調用了sendBroadcast(Intent)。非常感謝! – rogcg 2012-04-27 20:00:00

1

這對我有效。我在一個線程上啓動了一個後臺服務,該線程獲取值並更新單例中的對象。

在視圖控制器中,我啓動了一個定時器,它通過從singleton中的對象獲取數據來更新視圖。

我在理解整個問題文本時遇到了一些問題,所以我不確定您是否嘗試了這一點。但這是有效的。此外,該服務開始START_STICKY