为什么Android服务需要在UI线程上运行?

时间:2011-04-07 04:06:23

标签: android notifications ui-thread looper

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

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()的线程内创建处理程序”。

我明白我们需要创建looper和handler来与UI线程进行通信;对于影响UI的事件。但是获取位置会影响UI吗?是因为位置提供商还会尝试在我的手机顶部栏上绘制一个GPS图标,因为它没有在UI线程中运行;它不能那样做?

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

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

这些问题的任何指针和答案都会非常有用。在此先感谢您的帮助。

干杯

1 个答案:

答案 0 :(得分:1)

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