鉴于发布post()
的任务会将Runnable
放入队列,
protected void onCreate(Bundle savedInstanceState) {
Log.d("UI thread", "Do something");
}
和
protected void onCreate(Bundle savedInstanceState) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
Log.d("UI thread", "Do something");
}
});
}
在这两种情况下,应该只有一个线程在运行,并且没有发生并发 - 对吗?
那么创建一个附加到UI线程并在其上运行任务的处理程序的好处是什么?
答案 0 :(得分:3)
时机不同。在第一个片段中,代码作为onCreate
执行的一部分执行,因此保证在onCreate
返回之前完成,在第二个片段中,它会在一段时间后执行(可能在其他几个回调之后)
答案 1 :(得分:1)
那么创建附加到UI线程并在其上运行任务的处理程序有什么好处呢?
您的示例仅提供了大多数开发人员可能永远不会遇到的最小“用例”。在您的示例中,您可能希望启动后台服务,但是您希望确保在执行该工作之前启动服务的方法已完成,您的示例将完成该操作。此外,您可能希望确保在主/ UI线程上优先考虑服务构造。这种方法意味着您不必添加注释,例如“将此代码放在此方法的末尾”或具有其他“固有代码依赖性” - 对处理程序的调用保证方法执行后方法/结束。不是真的“正常”所以......
更有用的示例是当您有后台线程需要更新UI时。它可以在后台进行必要的处理,然后创建一个将在UI线程上适当执行的处理程序。这很常见,例如在AsyncTask
中实施(在getMainHandler()
方法中 - https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/AsyncTask.java#L282)
此外,处理程序允许Runnable
s的延迟执行。延迟执行通常有利于立即屏幕显示比完整屏幕显示更重要的情况。在大多数情况下,开发人员应该“延迟”延迟并让屏幕显示加载微调器或其他UI / UX装饰,但如果没有要求指定延迟的长度,那么您给出的示例将是在主线程循环队列上发布runnable以执行ASAP。这可能正是您想要做的,或者可能让其他可能需要维护代码的开发人员感到困惑(例如,您提出此问题的原因)。