Timertask或Handler

key*_*oze 96 performance android timer handler timertask

假设我想每10秒执行一次操作,并不一定需要更新视图.

问题是:使用带有timertask的计时器是否更好(我的意思是更有效率和更有效),如下所示:

final Handler handler = new Handler();

TimerTask timertask = new TimerTask() {
    @Override
    public void run() {
        handler.post(new Runnable() {
            public void run() {
               <some task>
            }
        });
    }
};
timer = new Timer();
timer.schedule(timertask, 0, 15000);
}
Run Code Online (Sandbox Code Playgroud)

或者只是一个带有postdelayed的处理程序

final Handler handler = new Handler(); 
final Runnable r = new Runnable()
{
    public void run() 
    {
        <some task>
    }
};
handler.postDelayed(r, 15000);
Run Code Online (Sandbox Code Playgroud)

如果您能解释何时使用哪种方法以及为什么其中一种方法比另一种方法更有效(如果它实际上是这样),我将不胜感激.

Sur*_*gch 87

Handler比...更好TimerTask.

Java TimerTask和Android Handler都允许您在后台线程上安排延迟和重复的任务.然而,文献绝大多数建议使用HandlerTimerTaskAndroid中(见这里,这里,这里,这里,这里这里).

一些报告的TimerTask问题包括:

  • 无法更新UI线程
  • 内存泄漏
  • 不可靠(并不总是有效)
  • 长时间运行的任务可能会干扰下一个预定的事件

我见过的各种Android示例的最佳来源是Codepath.这是一个Handler重复任务的例子.

// Create the Handler object (on the main thread by default)
Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnableCode = new Runnable() {
    @Override
    public void run() {
      // Do something here on the main thread
      Log.d("Handlers", "Called on main thread");
      // Repeat this the same runnable code block again another 2 seconds
      handler.postDelayed(runnableCode, 2000);
    }
};
// Start the initial runnable task by posting through the handler
handler.post(runnableCode);
Run Code Online (Sandbox Code Playgroud)

有关

  • @Reek不,GC应该照顾它.但是你需要处理为延迟执行而发布的runnable.在上面的示例中,runnable使用的是一个内部类实例,因此保存对包含类(可能是一个活动)的隐式引用.runnable将保留在处理程序的关联looper的消息队列中,直到它的下一个执行时间可能在上下文无效之后并且可能泄漏包含的类实例.你可以在适当的时候使用`mHandler.removeCallbacks(runnableCode)`清除这样的引用(例如`onStop()`用于一个活动). (5认同)
  • 最好的方式呈现参考!!! (见这里,这里,这里,这里,这里,这里). (5认同)

Pra*_*ena 18

使用Timer有一些缺点

它只创建单个线程来执行任务,如果任务运行时间太长,其他任务就会受到影响.它不处理由任务抛出的异常,并且线程只是终止,这会影响其他计划任务,并且它们永远不会运行

复制自:

TimerTask vs Thread.sleep vs Handler postDelayed - 每N毫秒最准确的调用函数?

  • 那么一次性任务怎么样?听起来好像Timer可能更好,因为你没有消息队列的开销? (6认同)
  • 我想我们永远不会知道 (2认同)

sma*_*871 8

接受答案的 Kotlin 版本:

// execute on the main thread, empty constructor is deprecated
val handler = Handler(Looper.getMainLooper())

val runnableCode = object : Runnable {
    override fun run() {
        Log.d("Handlers", "Called on main thread")
        handler.postDelayed(this, 2000)
    }
}

// or shorter using a lambda function
val runnableCode = Runnable {
    Log.d("Handlers", "Called on main thread")
    handler.postDelayed(this, 2000)
}

handler.post(runnableCode)
Run Code Online (Sandbox Code Playgroud)

  • 对于不需要更新 ui 的任务,添加在单独线程上运行的处理程序的示例会很有帮助。 (4认同)