繁体   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