Android Handler.getLooper() возвращает значение null
-
12-12-2019 - |
Вопрос
У меня следующая проблема.У меня есть такая реализация моего потока с помощью Looper.
public class GeoLocationThread extends Thread{
public Handler handler;
private General general;
public void run(){
Looper.prepare();
handler = new IncomingHandler(general);
Looper.loop();
}
public GeoLocationThread(General general){
this.general=general;
}
private static class IncomingHandler extends Handler{
private final WeakReference<General> mService;
IncomingHandler(General service) {
mService = new WeakReference<General>(service);
}
@Override
public void handleMessage(Message msg)
{
General service = mService.get();
if (service != null) {
Location location=service.getLl().getLocation();
if(location.getAccuracy()<40){
service.setOrigin(new GeoPoint((int) (location.getLatitude() * 1E6),(int) (location.getLongitude() * 1E6)));
}
}
}
}
}
и я хотел бы сделать следующее:
GeoLocationThread locationThread=new GeoLocationThread(this);
locationThread.start();
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, ll, locationThread.handler.getLooper());
Где lm - это LocationManager.Исходя из моего журнала и тестирования, я могу сказать, что locationThread.handler.getLooper()
возвращает null вместо Looper.
Я не знаю, почему оно равно нулю.Я пытался дозвониться locationThread.isAlive()
который вернул значение true.Я также пытался получить locationThread.handler;
который, как я знаю, не равен нулю.Я также много поискал в Google, но не нашел ничего, кроме документации.
Заранее большое вам спасибо за ваши ответы.
Решение
Ваш код считывается null
скорее всего, потому, что две операции не синхронны друг с другом.Вы не можете успешно вызвать getLooper()
на Handler
до тех пор Looper.prepare()
завершается, и обработчик создается.Потому что Thread.start()
не блокируется во время выполнения другого потока (конечно, с чего бы это?это противоречило бы цели нового потока) вы создали условие гонки между run()
блок потока и код, пытающийся настроить прослушиватель местоположения.Это приведет к разным результатам на разных устройствах в зависимости от того, кто сможет выполнить первым.
Кроме того, регистрация обновлений местоположения уже является асинхронным процессом, поэтому возникает вопрос, зачем нужен дополнительный поток?Вы можете просто запросить обновления у своего слушателя, не передавая вторичный запрос Looper
и слушатель получит опубликованные данные, когда будут доступны новые обновления, основной поток не остается заблокированным во время этого процесса.
Другие советы
Вам нужно позвонить супер () в вашем конструкторе?Может быть, петлитель не устанавливается, потому что родительский конструктор не вызывается?
Хорошо, попробуйте это.Сделайте это:
public class GeoLocationThread extends Thread{
.
Будь этим:
public class GeoLocationThread extends HandlerThread{
.
Тогда вы можете сделать это. GTELOOPER (), когда вы строим обработчик или когда вам нужен петвет.