Où “quitter” avec un looper?
J'ai un problème avec un looper. J'appelle looper.prepare()
, et après avoir fait quelque chose que tout fonctionne bien. Mais si j'ai faites pivoter l'appareil, j'obtiens une exception sur le préparer.
07-12 16:40:09.760: E/activity(15809): java.lang.RuntimeException: Only one Looper may be created per thread
Je suis en train de quitter le looper, mais il ne fait rien.
Voici mon AsyncTask:
@Override
protected String doInBackground(String... args) {
try{Looper.prepare(); //here start the exception
try {
URL url = new URL(link);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
utente.measure(0, 0);
bmImg = decodeSampledBitmapFromResource(is,(int) utente.getMeasuredWidth(), utente.getMeasuredHeight(), link);
if(bmImg!=null){
try{
getCroppedBitmap();
}catch(Exception e){
System.out.println(e);
}
}
}
catch (IOException e)
{
Log.e("lele", "errore qui");
e.printStackTrace();
}
Looper.myLooper().quit(); //do nothings
}catch(Exception e){
Log.e("canta tu", " "+e);
}
Looper.myLooper().quit(); //do nothings
return null;
}
@Override
protected void onPostExecute(String args) {
//Looper.myLooper().quit(); //generathed an error, main thread can't stop looper
if(bmImg!=null){
try{
utente.setImageBitmap(bmImg);
ellisse.setVisibility(View.VISIBLE);
}catch(Exception e){
Log.e("lele",""+e);
Log.e("lele","errore probabile out of bound");
}
}
else {
Toast.makeText(getApplicationContext(), "Modifica la foto da \"profilo\"", Toast.LENGTH_LONG).show();
}
Idées?
Vous devez vous connecter pour publier un commentaire.
Il y a deux cas à considérer:
(1) de l'arpenteuse de fils que vous souhaitez vivre l'ensemble de la durée de vie de l'application, et de ne pas tenir une forte référence à une vue (même pas implicitement)
Citant Ingénieur Google, Christopher Tate - vous pouvez simplement laisser le looper là jusqu'à ce que votre application est détruit, et il ira vers le bas avec elle. Vous n'avez pas besoin de s'inquiéter à ce sujet.
- Je utiliser un tel fil du boucleur comme un multi but HandlerThread, et envoyer Runnables à chaque fois que je veux quelque chose en dehors du thread principal (UI).
(2) de l'arpenteuse de threads qui font référence à un point de vue
Ce que l'on tombe hors de la recommandation de Christopher Tate, car il va provoquer la fuite de mémoire, par exemple si vous faites pivoter l'écran.
(Il est préférable de faire le thread de gestionnaire de statique et d'utiliser de faibles référence - et vous serez de retour avec l'option #1)
Pour le tuer, vous devez quitter la boucle. Pour ce faire, vous devez exécuter la commande quit sur le contexte de ce thread.
Afin de créer un message avec quelques quelle que soit int comme votre msg.ce qui, dans votre handleMessage attendre pour ce type int, et lorsqu'il arrive - appel:
Et n'oubliez pas de nulle toute référence à des points de vue et activités.
Envoyer ce tuer message au gestionnaire de votre activité
onDestroy()
Looper.prepare()
associe unLooper
-exemple avec le fil qu'il est appelé, maisLooper.quit()
ne pas supprimer cette association (il simplement s'arrête, le message d'expédition mécanisme). Ainsi, lorsque vous recevez un deuxième appel àLooper.prepare
unRuntimeException
est levée.La recommandation générale est de ne pas associer
Looper
-instances avecAsyncTask
-fils. LeLooper
est prévu pour la transmission de messages entre les threads, mais c'est déjà géré en interne par leAsyncTask
, de sorte que les données peuvent être envoyés entreonPreExecute
(thread d'INTERFACE utilisateur) ->doInBackground
(thread) ->onPostExecute
(thread d'INTERFACE utilisateur).Looper.prepare()
indique que vous êtes l'exécution d'une tâche qui nécessite une file d'attente de message sur ladoInBackground
thread, c'est à dire un Looper — mais je ne vois pas la partie du code qui aurait besoin d'unLooper
. Le thread d'arrière-plan utilisée avecAsyncTask
n'est pas prévu d'avoir un message de la file d'attente. Il serait préférable d'utiliser unHandlerThread
pour l'exécution en arrière-plan.