[英]Android Asynctask update UI and computation
I am a beginner at android/java development and I have just started learning about asynctask. 我是android / java开发的初学者,我刚开始学习asynctask。 I am trying to create an application that counts up (updating the ui thread with each incremental count) with a variable delay, and I am not sure how to pass the values into the asynctask, or even get it to work.
我正在尝试使用可变延迟创建一个计数(用每个增量计数更新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");
}
}
Now this code does not compile properly because it wants i to be a final variable, and I don't know how to make the i in for loop into a final variable, if possible. 现在这段代码编译不正确,因为它希望我成为一个最终变量,如果可能的话,我不知道如何将i for for循环变成最终变量。 I tried using a dummy variable and adding +1 every loop run and it still doesn't work.
我尝试使用虚拟变量并在每次循环运行时添加+1,但它仍然无效。 Additionally, when I tried to use the for loop/asynctask without the i value (a constant value) it would run but the ui thread would still hang like normal on large values.
另外,当我尝试使用for循环/ asynctask而没有i值(一个常量值)时,它会运行,但是ui线程仍然会像正常情况一样在大值上挂起。 Can somebody give me insight as to what I am doing wrong, and how I should correct it?
有人可以让我了解我做错了什么,以及我该如何纠正它? Thank you.
谢谢。
Couple problems. 夫妻问题。
runOnUiThread()
anywhere in AsyncTask
...it defeats the purpose. AsyncTask
任何地方使用runOnUiThread()
......它会破坏目的。 All functions of AsyncTask
run on the UI Thread
except for doInBackground()
so the idea is to do heavy work in doInBackground()
and update UI
in the other functions. doInBackground()
之外 , AsyncTask
所有函数都在UI Thread
上运行,因此我们的想法是在doInBackground()
执行繁重的工作并在其他函数中更新UI
。 onPostExecute()
expecting a String
but you are returning null
from doInBackground()
and that function passes its result
(if there should be one) to onPostExecute()
onPostExecute()
期望一个String
但你从doInBackground()
返回null
,并且该函数将其result
(如果应该有)传递给onPostExecute()
onProgressUpdate()
by calling publishProgress()
in doInBackground()
publishProgress()
中的doInBackground()
将更新传递给onProgressUpdate()
doInBackground()
To fix this you could do something like 要解决这个问题,你可以做点什么
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
}
I don't know how you are calling the task so I don't know what you are doing wrong there but you can do something like 我不知道你是怎么称呼任务的,所以我不知道你在做什么,但你可以做类似的事情
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() is a bad way to delay repetitions: Thread.sleep()是一种延迟重复的坏方法:
Why using System.Threading.Thread.Sleep() is a bad practice? 为什么使用System.Threading.Thread.Sleep()是一种不好的做法?
You can use a CountDownTimer: 您可以使用CountDownTimer:
Android CountDownTimer Android CountDownTimer
but if I were you, I would post a delayed execution N-times since you already have an existing view (your text field): 但如果我是你,我会发布延迟执行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.