【问题标题】:Why does Android service needs to run on UI thread?为什么Android服务需要在UI线程上运行?
【发布时间】:2011-07-31 08:33:32
【问题描述】:

我有一个可能很简单的问题。我有一个安卓服务;我在哪里创建了一个通用服务类,它请求锁定并在单独的线程中执行实际(扩展)服务代码。示例如下:

abstract public class ParentService extends Service {


public static void getLocks(Context context) {
       //code to get locks
}

public abstract void doServiceJob();

@Override
public void onCreate() {
    super.onCreate();       
    //Run the service code in separate thread
    Thread serviceThread = new Thread() {
        public void run() {
            //Looper.prepare();
            doServiceJob();
            //Looper.loop();
        }
    };
    serviceThread.start();
}

@Override
public void onDestroy() {
       //release locks
}
}

在上面的例子中;即使在调用的线程中没有调用 Looper.prepare() 和 Looper.loop() ,一切正常。

但是,如果我尝试通过 GPS 或网络获取位置;然后我有一个问题,代码没有运行说“无法在没有调用 Looper.prepare() 的线程内创建处理程序”。

我知道我们需要创建循环器和处理程序来与 UI 线程通信;对于影响 UI 的事件。但是获取位置会影响 UI 吗?是不是因为位置提供者也会尝试在我的手机顶部栏上绘制一个 GPS 图标,并且因为它没有在 UI 线程中运行;它不能那样做吗?

这里有什么问题,我可以通过调用 looper.prepare() 和 Looper.loop() 来解决这个问题;但是我需要了解以下内容?

  • 我知道服务在主线程上运行,与UI线程相同;这是否有效地意味着,服务有能力对 UI 进行更改,我们不这样做是因为它不是良好的用户体验,这就是为什么通过通知传达所有内容? (甚至通知也需要在 UI 线程上运行?)
  • 为什么位置提供程序需要在 UI 线程上运行?
  • 我没有在这里声明任何处理程序,我只是在调用 looper.prepare();那么消息队列是如何在后台工作的,以及在下面的 android 代码中会发生什么?

对这些问题的任何指示和答案都会非常有帮助。提前感谢您的帮助。

干杯

【问题讨论】:

  • 将应用程序的服务和活动放在同一线程上的决定可能是为了简化事情并降低 MT 成本。只是我的猜测:)。内核必须处理的线程更少,没有并发问题。

标签: android notifications ui-thread looper


【解决方案1】:

之所以必须调用 Looper.Loop,是因为它提供了后台操作在前台线程上执行代码的路径。来自后台线程的消息使用 Handler 对象发布到 UI 线程,而这些又需要 UI 线程调用 Looper.Loop 来获取实际的消息服务。这就是消息处理发生的地方:在 Looper.Loop 调用中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-03
    • 2011-06-25
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多