2013-07-04 1 views
1

Im, получая этот знаменитый «Невозможно создать обработчик внутри потока, который не вызвал ошибку Looper.prepare()» в моем нижнем коде. основанный на большинстве результатов поиска Google, это происходит, когда я пытаюсь обновить интерфейс из моего ни-ни-нить, но я не обновляю пользовательский интерфейс в этот момент, когда я вызываю метод из моего другого вспомогательного класса (только после того, как адрес был возвращается); поэтому, пожалуйста, проконсультируйтесь о том, почему это происходит, будет оценено по достоинству.Ошибка: не удается создать обработчик внутри потока, который не вызвал Looper.prepare()

package com.parspake.kookojapost; 

import android.app.ActionBar; 
import android.app.Activity; 
import android.content.Context; 
import android.content.Intent; 
import android.database.sqlite.SQLiteDatabase; 
import android.location.*; 
import android.os.Build; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Looper; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.EditText; 
import android.widget.TextView; 
import android.widget.Toast; 

public class TextShare extends Activity { 


    ConnectionHandler textPageConn; 
    TextView dt2; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.text_share); 

     textPageConn = new ConnectionHandler(this); 
     dt2 = (TextView) findViewById(R.id.show_location_text_page); 

     Thread thread1 = new Thread(new Runnable() { 

      @Override 
      public void run() { 

       textPageConn.getLocation(); 
       do { 

        if (textPageConn.mAddress != null) { 
         dt2.setText(textPageConn.mAddress); 
         break; 
        } else { 
         Log.d("debug","no location"); 
        } 

        try { 
         Thread.sleep(1000); 
        } catch (InterruptedException e) { 
         Thread.currentThread().interrupt(); 
        } 
       } while (textPageConn.mAddress == null); 
      } 

     }); 
     thread1.start(); 
    } 
} 

это исключение, которое я получаю:

07-04 23:59:38.730: E/AndroidRuntime(7149): FATAL EXCEPTION: Thread-8482 
07-04 23:59:38.730: E/AndroidRuntime(7149): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at android.os.Handler.<init>(Handler.java:121) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at android.location.LocationManager$ListenerTransport$1.<init>(LocationManager.java:183) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at android.location.LocationManager$ListenerTransport.<init>(LocationManager.java:183) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at android.location.LocationManager._requestLocationUpdates(LocationManager.java:661) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at android.location.LocationManager.requestLocationUpdates(LocationManager.java:486) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at com.parspake.kookojapost.ConnectionHandler.getLocation(ConnectionHandler.java:136) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at com.parspake.kookojapost.TextShare$2.run(TextShare.java:69) 
07-04 23:59:38.730: E/AndroidRuntime(7149):  at java.lang.Thread.run(Thread.java:856) 

так ConnectionHandler.java:136 есть -> mLocationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 10000, 50, mlocationListener);

и TextShare.java:69 is -> textPageConn.getLocation();

это мой ConnectionHandler Вспомогательный класс:

package com.parspake.kookojapost; 

import android.content.Context; 
import android.location.*; 
import android.net.ConnectivityManager; 
import android.net.NetworkInfo; 
import android.os.Bundle; 
import android.util.Log; 
import android.widget.Toast; 

import java.io.IOException; 
import java.util.List; 
import java.util.Locale; 

public class ConnectionHandler { 

    private Context ctx; 
    double mLat; 
    double mLong; 
    String currCity; 
    String currCountry; 
    String mAddress; 
    LocationManager mLocationManager; 
    LocationListener mlocationListener; 

    public ConnectionHandler(Context context) { 
     this.ctx = context; 
    } 


    public boolean locationSourceEnabled() { 
     mLocationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE); 
     boolean isInternetLocationAvailable = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     boolean isGpsAvailable = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 
     if (isInternetLocationAvailable) { 
      return true; 
     } else if (isGpsAvailable) { 
      return true; 
     } 
     return false; 
    } 


    public void getLocation() { 

     mlocationListener = new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 

       mLat = location.getLatitude(); 
       mLong = location.getLongitude(); 

       Geocoder gcd = new Geocoder(ctx, Locale.getDefault()); 
       List<Address> addresses; 
       try { 
        addresses = gcd.getFromLocation(mLat, mLong, 1); 
        if (addresses.size() > 0) { 
         currCity = addresses.get(0).getLocality(); 
         currCountry = addresses.get(0).getCountryName(); 
         mAddress = currCity + " - " + currCountry; 
        } 
       } catch (IOException e) { 
        Log.d("omid debug", e.getMessage()); 
       } 
      } 

      @Override 
      public void onStatusChanged(String s, int i, Bundle bundle) { 
      } 

      @Override 
      public void onProviderEnabled(String s) { 
      } 

      @Override 
      public void onProviderDisabled(String s) { 
      } 
     }; 
     mLocationManager = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE); 
     if (locationSourceEnabled()) { 
      if (mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) { 
       mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 10000, 50, mlocationListener); 
      } 
      if (mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) { 
       mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 10000, 50, mlocationListener); 
      } 
     } 
    } 
} 

ответ

2

Ok проблема заключается в том, что requestLocationUpdates асинхронный вызов, а это означает, что вам не нужно, чтобы запустить его в другом потоке, а также означает, что если вы пытаетесь вам эффективно сделать обработчик другого потока, который не разрешен. Таким образом, вместо этого вы можете удалить нить и просто запустить все это на OnCreate() (так как вы только делаете асинхронных вызовов)

ссылка: requestLocationUpdates gives error "Can't create Handler inside thread that has not called Looper.prepare()

Вместо этого вы могли бы поставить свои Синхронный звонки в другой теме ...

@Override 
public void onLocationChanged(Location location) { 
    new Thread(new Runnable() { 

     @Override 
     public void run() { 
      mLat = location.getLatitude(); 
      mLong = location.getLongitude(); 

      Geocoder gcd = new Geocoder(ctx, Locale.getDefault()); 
      List<Address> addresses; 
      try { 
       addresses = gcd.getFromLocation(mLat, mLong, 1); 
       if (addresses.size() > 0) { 
        currCity = addresses.get(0).getLocality(); 
        currCountry = addresses.get(0).getCountryName(); 
        mAddress = currCity + " - " + currCountry; 
       } 
      } catch (IOException e) { 
       Log.d("omid debug", e.getMessage()); 
      } 
     } 
    }).start(); 
} 
+0

также попытался использовать ваш код и по-прежнему получал такое же исключение Looper.prepare(). мой код ссылается на эту строку в моем вспомогательном классе ConnectionHandler: mLocationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 10000, 50, mlocationListener); – kevoroid

+0

Вы не смогли добавить код для ConnectionHandler? –

+0

уверен. добавлен в исходное сообщение. – kevoroid

1

Вы не можете обновить TextView из не-UI потока.

Использование runOnUiThread вместо:

runOnUiThread(new Runnable() { 

        @Override 
        public void run() { 
         dt2.setText(textPageConn.mAddress); 
        } 
       }); 
+0

я сделал. он не работал. после «do» я написал: runOnUiThread (new Runnable() {... then run() Override .. – kevoroid

+1

Я советую вам прокомментировать строку 'dt2.setText()' и написать 'Log.v (« MY_APP »,« здесь ») вместо этого. Если вы не получите' Looper.prepare() 'exception и видите« здесь »в журналах, то проблема в' setText() '. – azizbekian

+0

Я прокомментировал это и все еще получено исключение Looper.prepare()! – kevoroid

0

Его невозможно изменить содержимое пользовательского интерфейса в другом потоке .. вы можете решить эти проблемы в основном 2 способами

  • Использование г unOnUiThread() метод, его простой, но это не лучшая практика
  • Другой способ заключается в использовании обработчика с обратного вызова обработчика (обратный вызов с), его рекомендуется один

Я предлагаю использовать обработчик с методом обратного вызова. Здесь вы можете получить отличный учебник. handler with callback in thread

Смежные вопросы

 Смежные вопросы