2015-11-24 46 views
0

我正在使用Android Studio和模拟器​​android 4.1.2。 我的代码android处理程序 - 确定,定时器 - 不幸停止。为什么不同?

Timer timer = new Timer(); 
    timer.schedule(new TimerTask() { 
     @Override 
     public void run() { 
      myRun(); 
     } 
    },10000,10000); 

结果“不幸的是,应用程序已经停止”,但是我发现代码

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

请张贴您的错误日志。 – starkshang

回答

0

Timer执行上仅用于服务通过这个特殊的定时任务创建一个单独的线程任务。 Handler在其可能或可能不是UI线程的Looper线程上运行其任务。一般来说,如果你在一个单独的线程上使用Handler,这两个类之间没有太大的区别。但在Android中使用Handler和HandlerThread更为常见。

如果您需要与UI交互,你最好使用Handler

0

这是一个有趣的问题和答案在于android遵循的线程/ GUI策略。

我们知道,UI在主线程上运行。 Timer创建一个不同的线程,android不允许在另一个线程中更新UI。为什么?

假设,你已经开始在你的活动线程更新一个TextView和线程运行时,你移动到一些其他的应用程序。现在,主线程不再存在,当另一个线程尝试更新TextView时,它无法找到该TextView。结果,我们看到了崩溃。

现在让我来看看TimerTask和Handler之间的区别。

TimerTask创建一个新的线程,等待指定的时间,然后在同一个线程中执行run()方法。另一方面,Handler创建一个新的线程,等待指定的持续时间,然后返回主线程并在主线程(如果处理程序在主线程上)执行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); 

在这个线程要设置一个可运行的定时器的时间后对UI线程上运行。

+0

非常感谢你! –

相关问题