Почему служба Android должна работать в потоке пользовательского интерфейса? - PullRequest
2 голосов
/ 07 апреля 2011

У меня, наверное, простой вопрос.У меня есть сервис 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?

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

Ура

1 Ответ

1 голос
/ 02 мая 2011

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

...