Android并发使用

Android在不同的线程上并行执行代码有很多不同的方便。 但我不确定什么时候应该使用每一个,或者不同的方式是什么样的最佳实践。

  1. 何时/为什么要使用处理程序?

  2. 何时/为什么要使用装载机?

  3. 何时/为什么要使用AsyncTasks?

  4. 何时/为什么应该使用FutureTask?

  5. 何时/为什么要使用Executor?

  6. 什么时候/为什么应该使用线程/运行?

  7. 什么时候/为什么要使用Volley?

我错过了吗?

非常感谢您的帮助!

Solutions Collecting From Web of "Android并发使用"

你有一个相当大的组件列表,每个组件的地址略有不同。 我的经验中的两个主要冲突实际上是处理程序执行 程序之间,以及任务线程之间

概观

主题

线程是用于促进并发的底层系统机制。 线程存在于Windows,Unix等中,并且可以以任何系统认为合适的方式实现。 创build线程通常相当昂贵(甚至更多的是创build全新的进程)。 我不知道Dalvik虚拟机是依赖于Linux线程还是提供自己的线程实现。 根据这个Dalvik虚拟机架构文档 ,Dalvik VM只是使用Linux线程模型来进行线程实现。 然而,Dalvik虚拟机并不符合Android 4.0之前的Java语言规范的内存模型。

您可能知道,因为创build线程很昂贵,所以计划大量asynchronous计算的更好方法是使用pipe理的线程池(大小取决于基础硬件的function),并将任务简单地提供给pipe理器,进而在线程变得可用时调度任务。

Android处理程序

据我所知,历史的简短概述是Android开发早在Java 执行程序库/ api变得固化之前就开始了。 为了提供比原有的线程同步方法更less混淆的并发接口,并且为了便于在线程之间以良好方式传递消息,Android引入了Handlers 。 但是,除非我不正确地理解这一点,否则处理程序与Executors基本相同。 你将Messages(包含Runnables)或简单Runables传递给Handlers,这些消息就像Handler的Thread一样快速地排队和执行。

Java执行者

在Android中,线程之间的所有通信都是(或者应该 )通过线程的处理程序完成的(据我所知,排除了直接访问另一个线程的情况,并且可能需要同步)。 在新的Java中,执行程序在function上等同于处理程序,而FutureTasks等同于消息。 Runnables仍然是Runnables。 只需要执行代码就可以使用Runnable。 当计算需要asynchronous执行并且需要从计算中检索结果时使用FutureTask。 结果可以通过任何types的对象。 由于FutureTask实现了Future接口,因此您可以轻松地在一个线程中等待Future来parsing并获得结果。

装载机

装载器只是试图提供一个可重复使用的机制来加载数据(由一个活动消耗)。 尽pipe有文档,但Loader类并不是抽象的,也不需要仅仅用于asynchronous数据采集(尽pipe我不能想到在同步加载中使用它的情况,我还没有探究) 。 AsyncTaskLoader只是使用一个AsyncTask来执行Loader负责加载数据的方法。 装载机是没有必要的。

例子

主题

线程应该用来后退执行者或处理程序,或者,在其他情况下,你会知道什么时候你需要一个线程(如退回一个服务)。 通常应该避免使用自由的方式创build,执行和销毁的小任务的线程。

处理程序与执行程序

根据我的经验,在处理UI线程(运行Activity和/或View层次结构)和其他线程之间的消息传递时,最好使用Handlers。 但是,在实现自己的asynchronousfunction时,使用Executor或Handlers似乎是非常安全的。 例如,我可能有一个类pipe理从服务器获取的图像队列。 我可以简单地创build自己的执行程序,并按照我认为合适的方式向执行程序提供任务。 但是,当将消息消息传递回Activity,其中一个图像已经加载,并且应该使用结果数据设置视图时,我使用Activity的Handler(通过runOnUiThread()方法访问runOnUiThread()得到了最好的结果,创build一个在Activity的线程上运行并将Runnables发布给它的执行器。 目前还不清楚为什么后者不能一直工作(从文档来看),但我怀疑这样做会导致与Handler的runWithScissors()方法类似的行为。 (编辑,我现在意识到这是非常糟糕的做法,在一个线程上运行多个并发的“loopers” – 所以这样解释。)

我想一个好的经验法则可能是:

  • 在Android组件之间传递消息时使用处理程序。
  • 在实现自己的库或实用程序function时使用执行程序或处理程序。

Runnables vs FutureTasks vs AsyncTasks

如前所述,Runnables是用于在对象之间传递计算的简单接口。 只有在涉及到线程/执行程序/处理程序时才需要使用Runnables – 它们可以用来捕获状态并重用代码。

  • Runnables和FutureTasks与Executors一起使用。
  • AsyncTasks(隐式)与处理程序一起使用。 当你构造一个AsyncTask的时候,你提供了一个对这个活动的引用,而AsyncTask类则有助于在一个工作线程池的一个线程上执行doInBackground方法(这由一个执行程序进行内部pipe理)。 为此,处理程序用于在活动线程和任务线程之间传递消息。 然而,任务本身由Executorpipe理,并且在有可用的时候交给工作线程。

装载机

我不使用装载机。 但是,当您有需要加载的数据时,可能会使用这些数据,以便活动使用它们。 如果按照处理数据的方式处理ContentProvider方法,则可以使用CursorLoader和ContentProvider。

齐射

我从来没有用过排球,所以我怀疑这个频道有什么有用的见解。


免责声明:我不是Android历史上的权威。 无论如何,我希望总览有助于增加清晰度。