java-Android计时器更新textview(UI)
我正在使用计时器来创建秒表。 计时器通过增加整数值来工作。 然后,我想通过不断更新textview在活动中显示此值。
这是我在服务中尝试更新活动的textview的代码:
protected static void startTimer() {
isTimerRunning = true;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
elapsedTime += 1; //increase every sec
StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview
}
}, 0, 1000);
}
我在错误的线程中更新UI时遇到某种错误。
如何调整我的代码以完成不断更新textview的任务?
JDS asked 2020-06-22T00:42:42Z
8个解决方案
89 votes
protected static void startTimer() {
isTimerRunning = true;
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
elapsedTime += 1; //increase every sec
mHandler.obtainMessage(1).sendToTarget();
}
}, 0, 1000);
}
public Handler mHandler = new Handler() {
public void handleMessage(Message msg) {
StopWatch.time.setText(formatIntoHHMMSS(elapsedTime)); //this is the textview
}
};
上面的代码可以工作...
注意:必须在您的主线程中创建处理程序,以便您可以修改UI内容。
Nirav answered 2020-06-22T00:43:01Z
8 votes
您应该改用Handler每X秒更新一次UI。 这是另一个显示示例的问题:是否有时间延迟重复任务?
您的方法不起作用,因为您尝试从非UI线程更新UI。 这是不允许的。
inazaruk answered 2020-06-22T00:43:25Z
6 votes
StopWatch.time.post(new Runnable() {
StopWatch.time.setText(formatIntoHHMMSS(elapsedTime));
});
该代码块基于Handler,但您无需创建自己的Handler实例。
DongXu answered 2020-06-22T00:43:45Z
2 votes
TimerTask实现Runnable,这将使其成为线程。 您无需做一些工作就无法直接从其他线程直接更新主UI线程。您可以做的一件事是使用“异步任务”创建计时器并每秒发布一次更新,以更新UI。
Ashterothi answered 2020-06-22T00:44:06Z
2 votes
我假设StopWatch.time是对您的TextView的静态或公共引用。 而不是这样做,您应该实现一个BroadcastReceiver在计时器(从单独的线程运行)和TextView之间进行通信。
John Leehey answered 2020-06-22T00:44:26Z
2 votes
您可以使用以下实用程序:
/**
* Created by Ofek on 19/08/2015.
*/
public class TaskScheduler extends Handler {
private ArrayMap tasks = new ArrayMap<>();
public void scheduleAtFixedRate(final Runnable task,long delay,final long period) {
Runnable runnable = new Runnable() {
@Override
public void run() {
task.run();
postDelayed(this, period);
}
};
tasks.put(task, runnable);
postDelayed(runnable, delay);
}
public void scheduleAtFixedRate(final Runnable task,final long period) {
Runnable runnable = new Runnable() {
@Override
public void run() {
task.run();
postDelayed(this, period);
}
};
tasks.put(task, runnable);
runnable.run();
}
public void stop(Runnable task) {
Runnable removed = tasks.remove(task);
if (removed!=null) removeCallbacks(removed);
}
}
然后,在由UI线程运行的代码中的任何地方,您都可以像下面这样简单地使用它:
TaskScheduler timer = new TaskScheduler();
timer.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
time.setText(simpleDateFormat.format(GamePlay.instance().getLevelTime()));
}
},1000);
Ofek Ron answered 2020-06-22T00:44:50Z
1 votes
您可以使用处理程序。
此代码每秒钟增加一个计数器,并在textView上显示和更新计数器值。
public class MainActivity extends Activity {
private Handler handler = new Handler();
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.text);
startTimer();
}
int i = 0;
Runnable runnable = new Runnable() {
@Override
public void run() {
i++;
textView.setText("counter:" + i);
startTimer();
}
};
public void startTimer() {
handler.postDelayed(runnable, 1000);
}
public void cancelTimer() {
handler.removeCallbacks(runnable);
}
@Override
protected void onStop() {
super.onStop();
handler.removeCallbacks(runnable);
}
}
faraz khonsari answered 2020-06-22T00:45:15Z
-3 votes
timer.schedule(new TimerTask() {
@Override
public void run() {
//your actions
}
},1*1000);//1 sec
Dmitriy Shkregal answered 2020-06-22T00:45:30Z