Android中的Thread.run()和Handler.post()与Service之间有什么区别?

时间:2011-12-30 10:45:20

标签: java android multithreading service handler

一般建议在需要在不同线程中完成某些工作时在Android中使用Handler.post() 当我想在后台做一些工作时,我被建议开始Service

但是我觉得使用new Thread (new Runnable(){...} );比以往更方便。

但我担心手动创建新线程可能会在Android中表现不同,例如在使用Service时可能不会在内存不足时自动停止?

希望得到一个明确的答案,帮助我摆脱这种混乱。 ^ ^

3 个答案:

答案 0 :(得分:8)

在android中执行某些作业时,强烈建议使用Handler,因为:

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

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

Android中的处理程序与创建它们的线程绑定。每个Handler实例都与一个线程和该线程的消息队列相关联。当您创建一个新的Handler时,它被绑定到正在创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并在消息出来时执行它们队列。所以处理程序在Android中最安全。

虽然服务,但是来自http://developer.android.com/reference/android/app/Service.html

的一段代码

什么是服务?

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

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

服务不是线程。它本身不是从主线程开始工作的手段(以避免应用程序无响应错误)。 因此,服务本身实际上非常简单,提供两个主要特征:

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

应用程序的工具,可将其某些功能公开给其他应用程序。这对应于对Context.bindService()的调用,它允许对服务进行长期连接以便与服务进行交互。

最后是线程,

线程用于执行一些繁重的非视图函数,一些繁重的计算工作就像解析等,这样它就不会阻止你的UI并安全地执行所有工作......

答案 1 :(得分:2)

从UI调用线程违反了单线程模型:Android UI工具包不是线程安全的,必须始终在UI线程上进行操作。这就是为什么以下是替代而不是直接使用线程

  • Activity.runOnUiThread(可运行)
  • View.post(可运行)
  • View.postDelayed(Runnable,long)
  • 处理程序

Handler用于在UI线程和后台线程之间进行通信 AsyncTask用于在后台执行一些繁重的任务

如果你在后台有最轻的工作,那么使用处理程序进行更繁重的后台工作使用AsyncTask并在后台使用服务中做最重的工作

请参阅http://android-developers.blogspot.com/2009/05/painless-threading.html

示例

  • 要在列表视图中添加或删除数据,您可以使用处理程序
  • 从服务器获取XML数据并反映视图使用中的数据 AsynTask。 AsyncTask比线程更优选
  • 播放音乐文件使用服务

答案 2 :(得分:0)

处理程序用于在特定线程上运行代码。到目前为止最常见的用例是当你处于工作线程上下文并想在主(UI)线程上运行某些东西时...在这种情况下,你将在主线程上实例化一个Handler(在初始化期间,比方说) ,并从工作线程post()一个Runnable。

Thread.run()是基本的Java线程入口点。当你需要一个后台线程来做一些I / O或繁重的计算时你实现这个,除了在Android上你通常不这样做,因为它很多更容易使用AsyncTask,你在其中覆盖doInBackground( )对于您的工作线程代码(即您通常实现run()的位置)并使用您希望在工作任务完成后在UI线程上运行的代码覆盖onPostExecute()。

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