【问题标题】:What's the difference between Thread.run() and Handler.post() and Service in Android?Android 中的 Thread.run() 和 Handler.post() 和 Service 有什么区别?
【发布时间】:2011-12-30 10:45:20
【问题描述】:

在Android中需要在不同线程中做一些工作时,一般建议使用Handler.post()
当我想在后台做一些工作时,有人建议我启动一个Service

但我感觉像以前一样使用new Thread (new Runnable(){...} ); 更方便。

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

希望有一个明确的答案来帮助我摆脱这种困惑。 ^^

【问题讨论】:

    标签: java android multithreading service handler


    【解决方案1】:

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

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

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

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

    在服务期间,这是来自http://developer.android.com/reference/android/app/Service.html 的一段代码

    什么是服务?

    关于 Service 类的大部分困惑实际上都围绕着它不是什么:

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

    服务不是线程。它本身并不是一种脱离主线程工作的方法(以避免应用程序无响应错误)。 因此,Service 本身实际上非常简单,提供了两个主要功能:

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

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

    最后是线程,

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

    【讨论】:

    • 谢谢。我发现在PhoneGap 内部,它对来自webview 的每个请求都使用线程。所以只使用线程可能是安全且易于使用的。
    【解决方案2】:

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

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

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

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

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

    示例

    • 要在列表视图中添加或删除数据,您可以通过处理程序使用
    • 要从服务器获取 XML 数据并在您的视图中反映这些数据,请使用 异步任务。 AsyncTask 比线程更受欢迎
    • 播放音乐文件使用服务

    【讨论】:

      【解决方案3】:

      处理程序用于在特定线程上运行代码片段。到目前为止,最常见的用例是当您在工作线程上下文中并希望在主(UI)线程上运行某些东西时......在这种情况下,您将在主线程上实例化一个处理程序(例如在初始化期间) ,然后从工作线程 post() 一个 Runnable 给它。

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-17
        • 2014-08-19
        • 1970-01-01
        相关资源
        最近更新 更多