Android:RunOnUiThread vs AsyncTask

时间:2012-02-15 15:49:24

标签: android multithreading performance android-asynctask

我相信Google建议开发人员使用AsyncTask。 但是,我想知道它与使用'new Thread'然后在性能和内存效率方面调用'RunOnUiThread'有什么不同。

使用RunOnUithread的示例:

    // some code #1
    Thread t = new Thread("Thread1") {
        @Override
        public void run() {
            // some code #2
            runOnUiThread(new Runnable() {
                public void run() {
                    // some code #3 (that needs to be ran in UI thread)

                }
            });

        }
    };
    t.start();

VS

的AsyncTask:

onPreExecute() {
   // some code #1
}

doInBackground() {
   // some code #2
}

onPostExecute() {
   // some code #3
}

有哪些优点/缺点?

编辑:

我不是在寻找像'更容易看到代码','方便开发人员'等答案。 我实际上是在寻找幕后的技术差异。

例如,Paul Nikonowicz在下面的回答就是我想要的答案。 (但AsyncTask的行为相同)

5 个答案:

答案 0 :(得分:51)

使用new Thread时,每次执行时都会创建一个新线程。但是,AsyncTask使用最多128个线程的静态池,并且只要它存在就会重用旧线程。因此,在串行中运行AsyncTask 10次只会创建一个运行任务10次而不是10个线程的线程。

这是许多人之间的差异之一。

答案 1 :(得分:12)

从本质上讲,这是一种便利。 AsyncTask框架处理Thread池的管理,并提供简单易懂的界面。它是众所周知的 - 知道如何使用AsyncTask的人 - 可以在onPreExecute()onPostExecute()onProgressUpdate()中继续进行用户界面活动,以及所有"重举"在doInBackground()中完成,您无法触摸用户界面。

它使开发人员可以轻松拥有一个简单的后台任务,可以轻松地将更新发布到UI线程并在完成后返回结果。它不是魔术,它只是一种便利。

答案 2 :(得分:4)

主要的缺点是使用自己的线程会在调用完成后保持活动的活动。 Android会为您的所有主题提供活动时间。这会导致创建活动泄漏,最终导致您的应用程序运行速度非常慢,直到您的应用程序强制退出用户或操作系统。

您可以通过查看ADB中的流程来验证这一点。即使活动结束,您仍然会看到它在那里占用资源。

因此,如果您使用自己的线程,请确保您管理它。或者,只需使用android api。这是你的选择。

答案 3 :(得分:4)

根据thisAsyncTask更容易使用,但有一些限制如下:

  • 核心池大小和工作队列是固定的:5个池/ 10个元素
    • 它是硬编码的,无法更改
  • 主题优先级固定为
  • Thread
  • 一样,不支持异常处理

另外还有另外一点我还没弄明白。 您可以找到并检查full source code of AsyncTask,因为Android是开源的: - )

在Android中使用编码玩得开心!

答案 4 :(得分:1)

这些是非常不同的。

  • 首先在主线程上完成所有用户交互以及所有图形工作。
  • 第二个AsyncTask专为短期专用活动而设计,例如下载文件或上传部分数据。
  • 第三,因为所有UI和用户交互都是在主线程中完成的,如果你开始将东西推送到这个线程,设备似乎会滞后并且对用户命令的响应性会降低。

您希望在UI线程中运行某些内容的唯一原因是与小部件进行交互。除此之外,如果您想进行长时间处理,请使用AsyncTask

编辑:

您可以在单独的帖子中下载您的数据,我对此没有任何问题。当您想要更新UI时会出现问题。独自一人,无法从子线程修改UI。相反,您必须创建一个绑定到UI线程的处理程序,或创建一个预定在UI线程中运行的新线程(如您的示例所示)。这不仅乏味,而且是对资源的悲惨浪费。 AsyncTask可以简单有效地处理这个问题。

要解决你的最后一点,你是对的。 AsyncTask可以访问pre / postExecute中的主线程。但是,任务正在执行的处理(UI滞后的主要来源)不是。使用Task,UI只会根据您绘制的内容受到影响,而不是必须等待Task完成其工作以及它想要做的任何绘图。