Android并发使用 [英] Android concurrency usage

查看:92
本文介绍了Android并发使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Android有很多不同的方法在并发执行代码在不同的线程。
但是我不知道每一个应该使用什么或什么最好的做法是这些不同的方式。


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



  2. 何时/为什么要使用AsyncTask?

    何时/为什么要使用FutureTask?


  3. 何时/为什么要使用执行人?


  4. 何时/为什么要使用主题/可执行文件?是否使用齐射?




非常感谢您的帮助!

解决方案

相当大的组件列表,每个组件解决稍微不同的东西。我的经验中的两个主要冲突实际上是在处理程序执行程序任务线程 / p>

概述



主题



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



正如你可能知道的,因为创建线程很昂贵,调度大量异步计算的方法是使用管理的线程池(大小取决于底层硬件的功能),并且只是将任务提供给管理器,管理器反过来在线程可用时调度任务。



Android处理程序



简单介绍历史记录,我的理解是Android开发在Java Executor libraries / api变得固化之前的几天。为了提供比现有的线程同步方法更容易混淆的并发接口,并且为了方便消息在线程之间以良好的方式传递,Android引入了 em>。但是,除非我不正确地理解,处理程序基本上是与执行者相同的东西。您将消息(包含Runnables)或简单的Runables传递给处理程序,并且这些消息会像处理程序的线程一样处理排队和执行。



Java Executors



在Android中,线程之间的所有通信(或 >)通过线程的处理程序(根据我的知识,并排除情况下,你直接访问另一个线程内存和同步可能需要)。在新的Java中,Executors在功能上等同于Handlers,FutureTasks等同于Messages。 Runnables仍然是Runnables。当只需要执行代码时,使用Runnable。当需要异步地执行计算并且需要从计算中检索结果时,使用FutureTask。结果可以通过任何类型的对象。因为FutureTask实现了Future接口,你也可以很容易地在一个线程中等待Future来解析并获得结果。



Loaders



加载器只是试图提供一个可重复使用的机制来加载数据(由活动消耗)。尽管文档,Loader类不是抽象的,也不需要仅用于异步获取数据(虽然我不能想到一个情况下,你会使用它的同步加载,我还没有探索) 。 AsyncTaskLoader 只是使用一个AsyncTask来执行Loader的负责加载数据的方法。



示例



线程



线程应该用于返回执行器或处理程序,或者在其他情况下,您将知道什么时候需要线程(例如返回服务)。



处理程序与执行程序

















b

在我的经验中,当处理你的UI线程(运行Activity和/或View层次结构)和其他线程之间的消息传递时,似乎更好地坚持处理程序。但是,当实现自己的异步功能时,使用执行器或处理程序似乎是完全安全的。例如,我可能有一个类管理要从服务器获取的图像队列。我可以简单地创建我自己的执行器和馈送任务给执行者,因为我认为合适。但是,当传递消息消息回到其中一个图像已加载,并且视图应该设置与结果数据,我有最好的结果使用活动的处理程序(访问通过 runOnUiThread ()方法),而不是创建一个在Activity的线程上运行并向其发布Runnables的执行器。不清楚为什么后者不会一直工作(从文档,这是),但我怀疑这样做可以导致类似于处理程序的 runWithScissors()方法的行为。 (编辑,我现在知道在一个线程上运行多个并发的loopers是非常糟糕的做法。)



我猜测一个好的经验法则是:




  • 在Android组件之间传递讯息时使用处理常式。

  • 在实现自己的库或实用程序功能时使用Executors或处理程序。



Runnables vs FutureTasks vs AsyncTasks



如前所述,Runnables是一个用于在对象之间传递计算的简单接口。您不必仅在涉及线程/执行器/处理程序时才使用Runnables - 它们可用于捕获状态和重用代码。




  • Runnables和FutureTasks与Executors一起使用。

  • AsynchronousTasks(隐式地)用于处理程序。当你构造一个AsyncTask时,你提供一个对活动的引用,AsyncTask类便于从一个工作线程池(这是由Executor内部管理)的一个线程上执行doInBackground方法。为此,Handler用于在活动线程和任务的线程之间传递消息。



装载程序



我不使用Loaders。但是,当您具有需要加载的数据时,可以使用它们,以便Activity使用它。



Volley



p>我从来没有使用过排球,所以我怀疑我对这个频道有任何有用的见解。






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


Android has a lot of different facilitations of executing code on separate threads concurrently. But I'm not sure when each one should be used or what the best practices are for these different ways.

  1. When/Why should Handlers be used?

  2. When/Why should Loaders be used?

  3. When/Why should AsyncTasks be used?

  4. When/Why should FutureTask be used?

  5. When/Why should Executor be used?

  6. When/Why should Threads/Runnables be used?

  7. When/Why should Volley be used?

Have I missed any?

Thanks very much for the help!

解决方案

You have a pretty big list of components each of which address slightly different things. The two main conflicts in my experience are actually between Handlers vs. Executors, and Tasks vs. Threads.

Overview

Threads

Threads are the underlying system mechanism used to facilitate concurrency. Threads exist in Windows, Unix, etc., and may be implemented in any way a system sees fit. It is usually pretty expensive to create threads (and even-more-so to create entirely new processes). I do no know whether the Dalvik VM relies on Linux thread or provides its own Thread implementation. According to this Dalvik Virtual Machine Architecture document, the Dalvik VM simply uses the Linux threading model for its thread implementation. The Dalvik VM does not, however, conform to the Java Language Specification's memory model pre Android 4.0.

As you may know, because it is expensive to create threads, a better way to schedule lots of asynchronous computations is to use a managed pool of threads (size depending on the capabilities of your underlying hardware) and simply feed the tasks to the manager, which, in turn, schedules the tasks on threads as they become available.

Android Handlers

A short overview of the history as I understand it is that Android development began back in the days before the Java Executor libraries/api became solidified. To provide a less confusing concurrency interface than the old Threads and Synchronization methods available, and to facilitate message passing between threads in a nice manner, Android introduced Handlers. However, unless I'm understanding this incorrectly, Handlers are basically the same thing as Executors. You pass Messages (containing Runnables), or simply Runables, to Handlers and these messages get queued and executed as quickly as the Handler's Thread can well.. handle them.

Java Executors

In Android, all communication between threads is (or should be) done via a thread's handler (to my knowledge and excluding situations where you're directly accessing another threads memory and synchronization may be required). In new Java, Executors are functionally equivalent to Handlers, and FutureTasks are equivalent to Messages. Runnables are still Runnables. A Runnable is used when code simply needs to be executed. A FutureTask is used when a computation needs to be executed asynchronously and a result needs to be retrieved from the computation. The result can by any type of object. Because FutureTask implements the Future interface, you may also easily wait in one thread for the Future to resolve and get the result.

Loaders

Loaders are simply an attempt at providing a reusable mechanism for loading data (to be consumed by an activity). Despite the documentation, the Loader class is not abstract nor does it need to be used solely for the asynchronous acquisition of data (although I can't think of a case where you'd use it for synchronous loading, I have not explored that). The AsyncTaskLoader simply uses an AsyncTask to execute the Loader's methods responsible for loading data. Loaders are not necessary at all.

Examples

Threads

Threads should be used to back Executors or Handlers, or, in other cases, you will know when you need a thread (such as to back a Service). You should generally avoid Threads for small tasks that are created, executed, and destroyed in a liberal manner.

Handlers vs Executors

In my experience, it seems better to stick with Handlers when dealing with message passing between your UI thread (running an Activity and/or View hierarchy) and some other thread. However, it seems perfectly safe to use either Executors or Handlers when implementing your own asynchronous functionality. For example, I may have a class that manages a queue of images to be fetched from a server. I can simply create my own executor and feed tasks to that executor as I see fit. But, when passing a message message back to the Activity that one of the images has loaded and the view should be set with the resulting data, I've had best results using the Activity's Handler (accessed via the runOnUiThread() method) as opposed to creating an executor that runs on the Activity's thread and posting Runnables to it. It is unclear why the latter would not work all the time (from the documentation, that is) but I suspect doing so can result in behavior similar to a Handler's runWithScissors() method. (Edit, I'm now aware it is extremely bad practice to run multiple concurrent "loopers" on one thread -- so that explains that.)

I guess a good rule of thumb may be to:

  • Use Handlers when message passing between Android components.
  • Use Executors or Handlers when implementing your own library or utility functionality.

Runnables vs FutureTasks vs AsyncTasks

As stated earlier, Runnables are a simple interface used to pass computations between objects. You need not use Runnables only when threads/executors/handlers are involved -- they can be used to capture state and to reuse code.

  • Runnables and FutureTasks are used with Executors.
  • AsyncTasks are (implicitly) used with Handlers. When you construct an AsyncTask you provide a reference to the activity and the AsyncTask class facilitates the execution of the doInBackground method on one thread from a pool of worker threads (this is internally managed by an Executor). To do this a Handler is used to pass messages between the activity thread and the task's thread. The task itself is managed by an Executor, though, and handed off to a worker thread when one is available.

Loaders

I don't use Loaders. But, they may be used when you have data that you need to load in order for an Activity to use it. You can use a CursorLoader with a ContentProvider if you are following the ContentProvider idiom in terms of handling data.

Volley

I've never used volley so I doubt I have any useful insight on that channel.


Disclaimer: I am not an authority on Android history. Regardless, I hope the overview helps add clarity.

这篇关于Android并发使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆