Android异步任务更新UI和计算

Android异步任务更新UI和计算,android,Android,我是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

我是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");
    }
}
/*我有一个名为log的editText(我特意使用了editText),这应该是
作为操作的输出。
count是我希望日志显示的计数。
时间是我希望在打印每个数字之间设置的睡眠延迟*/
公共类backgroundsend扩展异步任务{
@凌驾
受保护的字符串doInBackground(字符串…参数){
//我希望我是要显示的数字的当前计数。
对于(inti=1;i耦合问题

  • 不要在
    AsyncTask
    中的任何地方使用
    runOnUiThread()
    。这会破坏目的。
    AsyncTask
    的所有功能都在
    UI线程上运行,除了
    之外,所以想法是在
    doInBackground()中做繁重的工作
    和更新其他功能中的
    UI
  • 您有一个
    onPostExecute()
    需要一个
    字符串
    ,但是您正在从
    doInBackground()
    返回
    null
    ,并且该函数将其
    结果
    (如果应该有)传递到
    onPostExecute()
  • 您可以通过调用
    doInBackground()中的
    publishProgress()
    将更新传递到
    onProgressUpdate()
  • 要解决这个问题,您可以做如下操作

        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()是延迟重复的一种不好的方法:

    您可以使用倒计时:

    但如果我是你,我会发布延迟执行N次,因为你已经有了一个现有的视图(你的文本字段):

    //重复次数
    私人静态最终整数重复=5;
    //磨坊延误
    专用静态最终整数延迟=100;
    //计数
    私人整数计数;
    最终可运行计数可运行=新可运行(){
    @凌驾
    公开募捐{
    如果(计数<重复次数){
    计数=计数+1;
    log.postDelayed(countingrunable,DELAY);
    }
    否则{
    //TODO调用方法、通知侦听器或诸如此类的操作更新已结束
    }
    }
    };
    ...
    //然后在你想要触发计数的地方
    log.postDelayed(countingrunable,DELAY);
    ...
    //在`Activity | Fragment.onDestroy()`中,确保删除回调
    log.removeCallbacks(countingRunnable);
    
    除了codeMagic回答中的注释外,
    异步任务
    真的不是你想要的方法。更好的方法是使用
    处理程序
    -请看这篇博文…@Squonk好文章!但我很好奇为什么
    处理程序
    比这里的
    异步任务
    好。它在某些方面更快或更有效吗?如果它在文章中提到了这一点,我很抱歉,也许我遗漏了什么。使用
    处理程序
    更有效、更简单。
    异步任务
    类实际上非常复杂,只需定期更新
    文本视图
    远远超出了您的需要。
    延迟(…)
    使用
    处理程序
    更通用,而且
    处理程序
    可以在更简单的代码中以更多的方式使用。@Squonk感谢您的回复。我同意
    异步任务
    在这里有些过火,但我只是不确定它在性能方面是否更有效。非常感谢您,codeMagic先生。如果有人需要,请提供进一步的参考其他人希望学习类似的东西,我使用了Squonik写的/codeMagic写的,我也使用了,因为它更适合我的应用程序。它现在可以工作了,尽管我需要时间来吸收知识。
    // 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);