2013-07-04 1 views
1

Im getting that famous "Impossible de créer un gestionnaire dans le thread qui n'a pas appelé Looper.prepare()" erreur dans mon code ci-dessous. basé sur la plupart de mes résultats de recherche Google, cela se produit lorsque j'essaie de mettre à jour l'interface utilisateur de mon thread non-ui, mais je ne mets pas à jour l'interface lorsque j'appelle la méthode de mon autre classe d'assistance (seulement après l'adresse revenu); alors s'il vous plaît consulter sur pourquoi cela se produit serait apprécié.Erreur: Impossible de créer le gestionnaire dans le thread qui n'a pas appelé 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(); 
    } 
} 

c'est l'exception que je reçois:

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) 

si ConnectionHandler.java:136 est -> mLocationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 10000, 50, mlocationListener);

et TextShare.java:69 est -> textPageConn.getLocation();

c'est ma ConnectionHandler Classe d'assistance:

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); 
      } 
     } 
    } 
} 

Répondre

2

Ok le problème est que requestLocationUpdates est un appel asynchrone, ce qui signifie que vous ne avez pas besoin de l'exécuter sur un autre thread et signifie également si vous essayez de vous faites efficacement un gestionnaire sur un autre thread qui n'est pas autorisé. Ainsi, au lieu que vous pouvez retirer le fil et il suffit d'exécuter tout cela sur onCreate() (puisque vous ne faites que des appels asynchrones)

Référence: requestLocationUpdates gives error "Can't create Handler inside thread that has not called Looper.prepare()

Au lieu de cela vous pouvez mettre vos appels syncronous dans un autre thread ...

@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

a également essayé votre code et obtient toujours la même exception Looper.prepare(). mon code fait également référence à cette ligne dans ma classe auxiliaire ConnectionHandler: mLocationManager.requestLocationUpdates (LocationManager.GPS_PROVIDER, 10000, 50, mlocationListener); – kevoroid

+0

pourriez-vous ajouter le code pour ConnectionHandler? –

+0

sûr. ajouté au message original. – kevoroid

1

Vous ne pouvez pas mettre à jour TextView à partir de fils non-UI.

Utilisation runOnUiThread à la place:

runOnUiThread(new Runnable() { 

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

je l'ai fait. ça n'a pas marché. après "do", j'ai écrit: runOnUiThread (new Runnable() {... puis run() Override .. – kevoroid

+1

Je vous conseille de commenter la ligne 'dt2.setText()' et d'écrire 'Log.v (" MY_APP "," ici ")' à la place.Si vous n'obtenez pas l'exception 'Looper.prepare()' et voyez le "ici" dans les journaux, que le problème est dans 'setText()'. – azizbekian

+0

je l'ai fait remarquer et toujours l'exception Looper.prepare()! – kevoroid

0

ce ne est pas possible de changer le contenu ui dans autre thread .. vous pouvez résoudre ces problèmes dans fondamentalement deux façons

  • en utilisant r unOnUiThread() méthode, son simple, mais ce n'est pas la meilleure pratique
  • Une autre façon est à l'aide de gestionnaire avec gestionnaire de rappel (Callback c), son recommandé un

Je vais vous suggérons d'utiliser gestionnaire avec méthode de rappel. Vous pouvez obtenir un excellent tutoriel ici. handler with callback in thread

Questions connexes