基础知识:在主线程中运行代码

时间:2018-01-04 11:02:42

标签: android android-asynctask

鉴于发布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线程并在其上运行任务的处理程序的好处是什么?

2 个答案:

答案 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。这可能正是您想要做的,或者可能让其他可能需要维护代码的开发人员感到困惑(例如,您提出此问题的原因)。