我想知道在Thread
的{{1}}方法中执行doInBackground
是否可行。我应该避免在我的代码上使用这种结构吗?如果是的话,我为什么要避免呢?这会导致我的应用程序无效吗?
答案 0 :(得分:4)
原则上,在doInBackground()
的{{1}}中启动主题没有问题,但有时你看到这不是因为它&#39这是正确的做法,但由于对AsyncTask
如何运作的误解。
关键是AsyncTask
将自动在后台(非GUI)线程上执行,而无需您自己为其创建线程。事实上,这是doInBackground()
的重点。因此,如果您想要在后台执行简单的线性任务,则可以使用AsyncTask
执行此操作,并且不需要进行任何手动创建线程。
如果您希望后台任务使用多个线程来完成,那么<em>可能想要在AsyncTask
中启动新线程的位置。假设您正在编写应用程序以检查各种服务器的在线状态,并在屏幕上显示有关其状态的信息。您在后台使用AsyncTask
进行网络访问;但是如果你以一种天真的方式做到这一点,你最终会逐一对服务器进行ping操作,这会相当缓慢(特别是如果一个人关闭,你需要等待超时)。更好的选择是确保每个服务器都在自己的后台线程上处理。然后你会有几个选项,每个选项都是可以防御的:
AsyncTask
。AsyncTask
的{{1}}内的每个服务器创建一个主题,然后确保doInBackground()
没有完成,直到所有单个主题都已完成(使用) AsyncTask
)。doInBackground()
内使用Thread.join()
/某种ThreadPool
/ fork / join结构,为您管理线程。我想说现代图书馆很少需要手动创建线程。库函数将为您管理所有这些,并从中获取一些乏味,并使其不易出错。上面的第三个选项在功能上等同于第二个选项,但只是使用了更多的高级机制,而不是用你的线程创建DIY。
我并不是说永远不会手动创建线程,但是每当你想要创建一个线程时,值得一问的是,是否有一个高级选项会为您更轻松,更安全地做到这一点。
答案 1 :(得分:3)
是的,但它确实取决于您的应用程序和您的使用情况。例如,在多线程可以在doInBackground方法中执行一个Thread 的AsyncTask。
server-client
应用中,您必须为每个传入的客户创建一个thread
,并且您还必须在另一个thread
上进行侦听。所以在另一个内部创建thread
是可以的。并且您可以使用asynctask
来倾听您的客户。
我应该避免在我的代码上使用这种结构吗?如果有, 我为什么要避免它?
如果您仔细设计,则无需避免,例如确保旋转时不会创建另一个asynctask
,因为例如,如果您的用户旋转5次,则创建5 asynctasks
并且在每个中你创建一个thread
,这意味着你将获得10 threads
,很快就会出现内存泄漏。
这会导致我的应用无效吗?你可以解释吗 请问这些问题。
我在上面做了回答,我认为更好的想法是使用Thread Pool
来最小化threads
创建asynctask
或将UI less fragment
包裹在asynctask
中的次数,这样你就可以确定了不管发生什么事都会有一个{{1}}。
答案 2 :(得分:2)
在任何更高级的编程语言中,都存在多任务的概念。基本上,用户需要在没有用户交互的情况下运行部分代码。通常为此开发一个线程。但在Android中,可以通过Thread
和AsyncTask
这三种方法中的任何一种来完成多任务处理。
<强>发强>
线程是并发执行单元。它有自己的调用堆栈。有两种方法可以在应用程序中实现线程。
一个是提供一个扩展Thread并覆盖其run()方法的新类。 另一个是在创建过程中提供一个带有Runnable对象的新Thread实例。 可以通过调用其“start”方法来执行线程。您可以通过调用其“setPriority(int)”方法来设置线程的“优先级”。
如果您在UI部分中没有任何影响,则可以使用线程。例如,您正在调用某些Web服务或下载某些数据,并在下载后将其显示在屏幕上。然后你需要使用带有线程的处理程序,这将使你的应用程序变得复杂,以处理来自线程的所有响应。
Handler允许您发送和处理与线程的MessageQueue关联的Message和Runnable对象。每个线程都有每个消息队列。 (与待办事项列表一样),线程将接收每条消息并处理它,直到消息队列为空。因此,当Handler进行通信时,它只是向调用者线程发出一条消息,它将等待处理。
如果您使用Java线程,则需要在自己的代码中处理以下要求:
<强>的AsyncTask 强>
AsyncTask可以正确,轻松地使用UI线程。此类允许在UI线程上执行后台操作和发布结果,而无需操纵线程和/或处理程序。异步任务由在后台线程上运行的计算定义,其结果在UI线程上发布。
AsyncTask将经历以下4个阶段:
<强> 1。 onPreExecute()强>
在执行任务之前在UI线程上调用
<强> 2。 doInbackground(PARAMS ..)强>
在onPreExecute()完成执行后立即在后台线程上调用。
第3。 onProgressUpdate(进步..)强>
在调用publishProgress(Progress ...)之后在UI线程上调用。
<强> 4。 onPostExecute(结果)强>
在后台计算完成后在UI线程上调用。
互联网上有很多好的资源可以帮助你:
http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html http://www.mergeconflict.net/2012/05/java-threads-vs-android-asynctask-which.html
答案 3 :(得分:0)
如果你需要在AsyncTask
旁边同时运行某些东西,我会说没有问题。
一个问题可能是可读性(使用两种不同的并发方式),但我真的看不出其中的危害 - 特别是如果其中一个任务需要在UI中显示它的结果而另一个没有“T