Передача контекста для вызова "getSystemService" - PullRequest
0 голосов
/ 15 ноября 2011

Мое приложение аварийно завершает работу при обращении к службе определения местоположения в методе, который вызывается в потоке. Я передаю контекст из службы, в которой запущен поток, но он не работает.

Это вызов LocationService в потоке, который создается внутри службы.

class MyService extends Service {

  @Override 
  public int onStartCommand(Intent intent, int flags, int startId) {

  Thread thread = new Thread(){
    @Override
    public void run() {

      try{
        geofix = new GeoFixer(getApplicationContext());
        geofix.startLocationObserver(); 
        ...
      }catch (....){}....

Конструктор GeoFixer берет контекст и сохраняет его в Context context.

Теперь внутри метода startLocationObserver() я вызываю getSystemService с этим контекстом, который завершает работу приложения.

public class GeoFixer {
  ... 
  private Context context;

  GeoFixer(Context context){
    this.context = context; 
  }

  public void startLocationObserver(){
     LocationManager locationManager = (LocationManager)     
     context.getSystemService(Context.LOCATION_SERVICE);
  // This is where it crashes
  ... }

Что я делаю не так?

РЕДАКТИРОВАТЬ: Вот LogCat сейчас.

ERROR/AndroidRuntime(8824): FATAL EXCEPTION: Thread-10
ERROR/AndroidRuntime(8824): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
ERROR/AndroidRuntime(8824): at android.os.Handler.<init>(Handler.java:121)
ERROR/AndroidRuntime(8824): at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:173)
ERROR/AndroidRuntime(8824): at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:173)
ERROR/AndroidRuntime(8824): at android.location.LocationManager._requestLocationUpdates(LocationManager.java:579)
ERROR/AndroidRuntime(8824): at android.location.LocationManager.requestLocationUpdates(LocationManager.java:446)
ERROR/AndroidRuntime(8824): at de.theapplication.GeoFixer.getNetworkLocation(GeoFixer.java:64)
ERROR/AndroidRuntime(8824): at de.theapplication.GeoFixer.startLocationObserver(GeoFixer.java:27)
ERROR/AndroidRuntime(8824): at de.theapplication.Fadenzieher$1.run(Fadenzieher.java:36)

Ответы [ 3 ]

0 голосов
/ 15 ноября 2011

Глядя на трассировку стека, похоже, что ваш startLocationObserver() метод вызвал метод LocationManager requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) (метод без аргумента Looper).

Проверьте, можете ли вы вызвать requestLocationUpdates() версия с аргументом Looper, передавая Looper.getMainLooper().

В качестве альтернативы, смотрите сообщение в блоге , где решение состоит в том, чтобы вызвать Looper.myLooper().prepare().

0 голосов
/ 15 ноября 2011

Получите ссылку на LocationService в onStartCommand() (основной поток / поток пользовательского интерфейса) и передайте ее в свой поток.

А почему вы не хотите использовать IntentService? Он позаботится о запуске вашего кода в отдельном потоке и завершит свою работу после завершения.

0 голосов
/ 15 ноября 2011

Из быстрого поиска в Google кажется, что у рабочего потока нет связанного с ними Looper, поэтому ваш Runnable может пытаться отправить сообщение в поток, который не может их обработать.Попробуйте опубликовать тот же Runnable в вашем потоке пользовательского интерфейса и посмотрите, если ошибка все еще происходит.

Источник:

Не удается создать обработчик внутри потока, который не вызвал Looper.prepare ()

...