我正在使用Android Studio和模拟器android 4.1.2。 我的代码
Timer timer = new Timer ();
timer.schedule(new TimerTask() {
@Override
public void run() {
myRun();
}
},10000,10000);
导致“不幸的是,app停止了”,但我发现了代码
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
myRun();
}
}, 2000);
运行正常并按我的预期显示。 两者之间的内在差异是什么?
P.S。
public void myRun () {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
我正在尝试永久更新自定义视图,直到用户取消它。只需循环
while (myRun) {
导致模拟器甚至无法响应甚至后退按钮,在第二个线程中运行该更新
new Thread(new Runnable() {
@Override
public void run() {
while (myRun) {
myView.post(new Runnable() {
public void run() {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
});
}
}
}).start();
结果相同(有趣的是,如果我在第二个线程中运行带有断点的调试,屏幕更新,因为我预期很多次,但运行w / out调试不会更新屏幕)。
答案 0 :(得分:0)
Timer
在一个单独的线程上执行其任务,该线程仅用于提供由此特定计时器创建的任务。 Handler
在其Looper的线程上运行其任务,该线程可能是也可能不是UI线程。一般来说,如果在单独的线程上使用Handler,这两个类之间没有太大区别。但在Android中使用Handler和HandlerThread更为常见。
如果您需要与用户界面进行互动,最好使用Handler
。
答案 1 :(得分:0)
您可以在这里找到答案:Handler vs Timer
去看看吧。 :)
答案 2 :(得分:0)
这是一个有趣的问题和答案在于android遵循的线程/ GUI策略。
众所周知,UI在主线程上运行。 Timer创建一个不同的线程,android不允许在不同的线程中更新UI。为什么呢?
假设您已经在活动中启动了一个更新TextView的线程,并且在线程运行时您移动到其他应用程序。现在,主线程不再存在,当另一个线程尝试更新TextView时,它无法找到TextView。结果,我们看到了崩溃。
现在让我来看看TimerTask和Handler之间的区别。
TimerTask创建一个新线程,等待指定的时间,然后在同一个线程中执行run()方法。另一方面,Handler创建一个新线程,等待指定的持续时间然后返回主线程并在MAIN线程上执行run()方法(如果处理程序在主线程上)。因此,它工作正常。
但是你也可以用计时器来做。 请参阅以下代码:
final Runnable setRunnable = new Runnable() {
public void run() {
myView.removeAllViews();
drawView = new DrawView(myContext, myView);
myView.addView(drawView);
}
};
TimerTask task = new TimerTask(){
public void run() {
getActivity().runOnUiThread(setRunnable);
}
};
Timer timer = new Timer();
timer.schedule(task, 1000);
在此主题中,您将设置一个runnable,以便在计时器的持续时间后在UI线程上运行。