Почему служба Android должна работать в потоке пользовательского интерфейса?

У меня наверное простой вопрос. У меня есть служба 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 ()».

Я понимаю, что нам нужно создать цикл и обработчик для связи с потоком пользовательского интерфейса; для событий, влияющих на пользовательский интерфейс. Однако влияет ли выбор местоположения на пользовательский интерфейс? Это потому, что провайдер местоположения также попытается нарисовать значок GPS на верхней панели моего телефона и поскольку он не работает в потоке пользовательского интерфейса; это нельзя сделать?

В чем здесь проблема, я могу решить эту проблему, вызвав looper.prepare() и Looper.loop(); однако мне нужно понять следующие вещи?

  • Я знаю, что служба работает в основном потоке, который совпадает с потоком пользовательского интерфейса; Означает ли это, что служба может вносить изменения в пользовательский интерфейс, а мы этого не делаем, потому что это неудобный пользовательский интерфейс, и поэтому сообщать обо всем через уведомления? (Даже уведомления должны запускаться в потоке пользовательского интерфейса?)
  • Почему поставщику местоположения необходимо работать в потоке пользовательского интерфейса?
  • Я не объявляю здесь никакого обработчика, я просто вызываю looper.prepare(); так как же очередь сообщений работает в фоновом режиме и что происходит внизу в коде Android?

Любые указатели и ответы на эти вопросы будут действительно полезны. Заранее спасибо за помощь.

Ваше здоровье


person Priyank    schedule 07.04.2011    source источник
comment
Решение поместить сервис и действия приложения в один и тот же поток могло быть принято для упрощения и снижения затрат на МП. Только мое предположение :). Меньше потоков, с которыми приходится иметь дело ядру, нет проблем с параллелизмом.   -  person seand    schedule 07.04.2011


Ответы (1)


Причина, по которой вы должны вызывать Looper.Loop, заключается в том, что он предоставляет маршрут, по которому фоновые операции выполняют код в потоке переднего плана. Сообщения из фоновых потоков отправляются в поток пользовательского интерфейса с помощью объектов Handler, а они, в свою очередь, требуют, чтобы поток пользовательского интерфейса вызывал Looper.Loop для получения фактических сообщений. Вот где происходит обработка сообщения: внутри вызова Looper.Loop.

person edrowland    schedule 02.05.2011