我仍然对线程感到困惑。我仍然可以看到一些指向线程,UI线程,后台线程,主线程等的答案(主要是在AsyncTasks和从后台线程更新UI等)。
至少有人能给我一些关于这些或某些链接的完整解释吗?
如果答案涵盖以下情况,那就太棒了:
所涉及的所有主题都是:
答案 0 :(得分:1)
后台服务(服务)默认情况下,服务在与应用程序相同的进程中运行。在自己的线程中。 (正如@MisterSmith所指出的)默认情况下,服务在与应用程序相同的进程中运行。在自己的线程中。因此,您需要在服务中使用异步处理来在后台执行资源密集型任务。在应用程序进程中运行的服务有时称为本地服务。
您可以指定在自己的流程中运行服务:
如果服务在其主线程中执行长时间运行的操作,则在其自己的进程中运行服务不会阻止应用程序。但是,当服务在其自己的进程中运行时,您需要使用一些进程间通信(IPC)从其他部分与您的服务进行通信。
HttpClient
执行HTTP调用(来自docs:HTTP客户端的线程安全取决于实现和 特定客户的配置。
),必须使用new Thread(new Runnable(...)).start();
在非UI线程上执行,否则,由于@vikram,您将获得NetworkOnMainThreadException
。但似乎HttpClient.execute()
方法在一个线程中执行,这就是为什么它需要一个处理程序作为参数之一,以便将结果传递给相应的处理程序(处理程序在UI线程上运行并且可以更新小部件(UI)元素)因为它是必要的)
额外:
要强制在主要主题上执行某些内容,请使用yourContextInstance.runOnUiThread(new Runnable(....));
为了确定当前线程是否是UI(主)线程:
Looper.getMainLooper()。getThread()== Thread.currentThread();
有关服务中线程的有趣问题:
Does a runnable in a service run on the UI thread
为什么UI线程负责所有这些?
的一部分因为UI线程负责将事件分派给 适当的小部件(UI元素),包括绘图事件
答案 1 :(得分:1)
当我运行活动时(设置内容视图,附加一些按钮,一些对话框消息)
通常只有一个线程(主线程,有时被错误地称为UI线程)。
活动 - 使用异步任务
再次,默认只有一个(主要的一个)。菜单和按钮处理程序也在主线程中运行。 AsyncTask
是另一回事。它会创建一个工作线程(顺便说一下,在退出活动时应注意不要泄漏它)。
后台服务
主服务中默认运行服务。广播接收器也是如此。这就是主线程不是(仅)UI线程的原因。某些类型的服务(如流行的IntentService
)会产生一个工作线程。
http呼叫
是同步操作,因此它会一直阻塞直到它完成(这就是为什么你不应该在主线程中执行一个操作)。
答案 2 :(得分:0)
从技术上讲,应用程序可以拥有任意数量的线程,它们是由程序员任意创建的。
但是,标准的android应用程序默认有一个线程。这是主线程,通常被称为UI线程(因为它是唯一可以访问UI的线程)。默认情况下,一切都发生在主线程中。
如果你运行异步任务,不同的部分在不同的线程中运行,这是一个基本的细分:
onPreExecute()
在UI线程中运行,并在执行异步任务时首先调用。
doInBackground()
在与main / UI线程分开的新生成的线程中运行。
后台任务返回后,onPostExecute()
在UI线程中运行。
后台服务完全独立于应用程序运行,即使原始应用程序被销毁,它也可以无限期运行。
http调用发生在你调用它的任何线程上,但作为新的android API的要求,你不能再从主/ UI线程做任何网络活动。 (这实际上会导致异常并终止您的应用程序)这是为了防止慢速网络呼叫阻塞主线程,从而产生不稳定的用户体验。
答案 3 :(得分:0)
所涉及的所有主题都是:
当我运行活动时(设置内容视图,附加一些按钮,一些对话框消息)
此处涉及UI线程或主线程。
使用AsyncTask的活动
涉及UI线程和WorkerThread。
AsyncTask可以正确,轻松地使用UI线程。此类允许您执行后台操作并在UI线程上发布结果,而无需操作线程和/或处理程序。
4个步骤
执行异步任务时,任务将经历4个步骤:
onPreExecute()
,在执行任务之前在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。
doInBackground(Params...)
,在onPreExecute()
完成执行后立即在后台线程上调用。此步骤用于执行可能需要很长时间的后台计算。此步骤还可以使用publishProgress(Progress...)
发布一个或多个进度单位。这些值发布在UI线程的onProgressUpdate(Progress...)
步骤。
onProgressUpdate
(进度...),在调用publishProgress(Progress...)
后在UI线程上调用。此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。
onPostExecute
(Result),在后台计算完成后在UI线程上调用。后台计算的结果作为参数传递给此步骤。
后台服务
IntentService类提供了在单个后台线程上运行操作的简单结构。这使它能够处理长时间运行的操作,而不会影响用户界面的响应性
HTTP呼叫
无法从UI线程(或MainThread)执行NetwokrkOperation。因此,请使用AsyncTask或HandlerThread
等替代方案相关帖子:
Handler vs AsyncTask vs Thread