簡體   English   中英

Android Asynctask更新UI和計算

[英]Android Asynctask update UI and computation

我是android / java開發的初學者,我剛開始學習asynctask。 我正在嘗試使用可變延遲創建一個計數(用每個增量計數更新ui線程)的應用程序,我不知道如何將值傳遞到asynctask,甚至讓它工作。

/*I have an editText (I used editText on purpose) named log, which is supposed 
to be the output of the operation. 
count is the number of counting up that I want the log to display. 
time is the sleep delay I wish to set inbetween printing each number.*/

    public class backgroundsend extends AsyncTask<String, Integer, String>{
    @Override
    protected String doInBackground(String... params) {
//and I want i to be the current count of the number to be displayed.
       for (int i=1; i<count+1; i++){
            try {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        log.setText(log.getText() +i);
                    }
                });
                Thread.sleep(time);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        return null;
    }
    @Override
    protected void onProgressUpdate(Integer... values) {
    }
    @Override
    protected void onPostExecute(String result){
        log.setText(log.getText() + "Operation Ended \n\n");
    }
}

現在這段代碼編譯不正確,因為它希望我成為一個最終變量,如果可能的話,我不知道如何將i for for循環變成最終變量。 我嘗試使用虛擬變量並在每次循環運行時添加+1,但它仍然無效。 另外,當我嘗試使用for循環/ asynctask而沒有i值(一個常量值)時,它會運行,但是ui線程仍然會像正常情況一樣在大值上掛起。 有人可以讓我了解我做錯了什么,以及我該如何糾正它? 謝謝。

夫妻問題。

  1. 不要在AsyncTask任何地方使用runOnUiThread() ......它會破壞目的。 除了 doInBackground() 之外AsyncTask所有函數都在UI Thread上運行,因此我們的想法是在doInBackground()執行繁重的工作並在其他函數中更新UI
  2. 你有onPostExecute()期望一個String但你從doInBackground()返回null ,並且該函數將其result (如果應該有)傳遞給onPostExecute()
  3. 您可以通過調用publishProgress()中的doInBackground()將更新傳遞給onProgressUpdate() doInBackground()

要解決這個問題,你可以做點什么

    protected String doInBackground(String... params) 
    {
       for (int i=1; i<count+1; i++)
       {
            publishProgress(i);   update UI in onProgressUpdate()
            Thread.sleep(time);
        } 
     }
        return "Operation Ended \n\n";
    }

    @Override
    protected void onPostExecute(String result){
       log.setText(log.getText() + result);
    }
    @Override
    protected void onProgressUpdate(Integer... values) 
    {
        // update UI here 
    }

我不知道你是怎么稱呼任務的,所以我不知道你在做什么,但你可以做類似的事情

backgroundsend myTask = new backgroundsend();  // can pass params to a constructor if needed
myTask.execute(...); // the ... is where you would put params to pass to doInBackground()

Thread.sleep()是一種延遲重復的壞方法:

為什么使用System.Threading.Thread.Sleep()是一種不好的做法?

您可以使用CountDownTimer:

Android CountDownTimer

但如果我是你,我會發布延遲執行N次,因為你已有一個現有的視圖(你的文本字段):

// number of repetitions
private static final int REPETITIONS = 5;
// delay in mills
private static final int DELAY = 100;
// count
private int count;
final Runnable countingRunnable = new Runnable() {
    @Override
    public void run() {
        if (count < REPETITIONS)  {
            count = count + 1;
            log.postDelayed(countingRunnable, DELAY);
        }
        else {
            // TODO call a method, notify a listener or whatnot your updates are over
        }
    }
};
...
// then in your place where you want to trigger the counting
log.postDelayed(countingRunnable, DELAY);
...
// and in `Activity|Fragment.onDestroy()` ensure to remove the callbacks
log.removeCallbacks(countingRunnable);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM