[英]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线程仍然会像正常情况一样在大值上挂起。 有人可以让我了解我做错了什么,以及我该如何纠正它? 谢谢。
夫妻问题。
AsyncTask
任何地方使用runOnUiThread()
......它会破坏目的。 除了 doInBackground()
之外 , AsyncTask
所有函数都在UI Thread
上运行,因此我们的想法是在doInBackground()
执行繁重的工作并在其他函数中更新UI
。 onPostExecute()
期望一个String
但你从doInBackground()
返回null
,并且该函数将其result
(如果应该有)传递给onPostExecute()
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:
但如果我是你,我会发布延迟执行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.