在安卓中,Thread.run()、Handler.post()和Service有什么区别?

4
一般建议在Android中使用Handler.post()来在不同的线程中执行一些任务。
当我想在后台执行一些任务时,建议启动一个Service
但是我觉得使用new Thread (new Runnable(){...} );更加方便,因为我已经习惯了它。但是我担心手动创建新线程在Android中可能会表现不同,例如在内存不足时自动停止,而使用Service则可能不会?希望能得到明确的答案来帮助解决我的困惑。^ ^
3个回答

8

在Android开发中,执行某些任务时强烈建议使用Handler,因为:

在Android中,只能在原始线程(即创建它们的线程)中更新视图,否则应用程序可能会抛出异常,提示:

android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

Android中的处理程序与它们创建的线程绑定。每个处理程序实例都与单个线程及其消息队列相关联。当您创建新的处理程序时,它被绑定到创建它的线程/消息队列 - 从那时起,它将向该消息队列传递消息和可运行项,并在它们出现在消息队列中时执行它们。因此,在Android中,处理程序是最安全的。

而对于服务,以下是来自http://developer.android.com/reference/android/app/Service.html的代码片段:

什么是服务?

大多数关于Service类的混淆实际上都围绕着它不是什么展开:

服务不是一个独立的进程。服务对象本身并不意味着它在自己的进程中运行; 除非另有说明,否则它将在与其所属应用程序相同的进程中运行。

服务不是一个线程。它本身不是执行主线程之外工作的手段(以避免应用程序无响应错误)。 因此,服务本身实际上非常简单,提供两个主要功能:

一种让应用程序告诉系统它想要在后台执行某些操作的方法(即使用户没有直接与应用程序交互)。这对应于对Context.startService()的调用,它要求系统为服务安排工作,直到服务或其他人明确停止它。

一种让应用程序向其他应用程序公开其某些功能的方法。这对应于对Context.bindService()的调用,它允许建立长期连接以与服务进行交互。

最后是线程:

线程用于执行一些重型非视图函数,例如解析等重型计算工作,以便不会阻塞您的UI并安全地执行所有工作...


谢谢。我发现在PhoneGap内部,它为来自webview的每个请求使用线程。因此,仅使用线程可能是安全且易于使用的。 - Aloong

2
调用UI线程违反了单线程模型:Android UI工具包不是线程安全的,必须始终在UI线程上进行操作。因此,以下是使用线程的替代方法:
  • Activity.runOnUiThread(Runnable)
  • View.post(Runnable)
  • View.postDelayed(Runnable, long)
  • Handler
Handler用于在UI线程和后台线程之间通信。AsyncTask用于在后台执行一些较小的重任务。
如果您有轻量级的后台工作,则使用handler。对于更重的后台工作,请使用AsyncTask。要在后台执行最重的工作,请使用service。
请参见http://android-developers.blogspot.com/2009/05/painless-threading.html示例
  • 要向列表视图添加或删除数据,可以使用handler
  • 要从服务器获取XML数据并将其反映在视图中,请使用AsynTask。与线程相比,AsyncTask更受欢迎
  • 要播放音乐文件,请使用service

0

处理程序是用于在指定线程上运行代码片段的。迄今为止最常见的用例是当您处于工作线程上下文并想要在主(UI)线程上运行某些内容时......在这种情况下,您将在主线程上实例化Handler(例如在初始化期间),并从工作线程post()一个Runnable到它上面。

Thread.run() 是基本的Java线程入口点。当您需要一个后台线程执行某些I/O或者重型计算时,您可以实现此方法,但在Android中通常不需要,因为使用AsyncTask会更加容易,您可以在其中覆盖doInBackground()以编写工作线程代码(即通常实现run()的地方),并覆盖onPostExecute()以编写您希望在工作任务完成后在UI线程上运行的代码。

服务是完全不同的东西......它们不是线程。服务代码将在主线程上运行,与您的UI一起运行。您仍然可以从它们使用AsyncTask等,或者使用一种称为IntentService的特殊类型的服务,在工作线程上执行它的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接