Erro Android: Only one looper may be created per thread

Olá pessoal!

Segue abaixo minha classe para trabalhar com Dialogs no Android:

[code]package br.com.tdta.service.view;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Looper;

public class MessageDialog {

public static void showOkDialog(Activity context, String msg) {
	Looper.prepare();
	final Looper myLooper = Looper.myLooper();

	final AlertDialog.Builder builder = new AlertDialog.Builder(context);
	builder.setMessage(msg).setNeutralButton("OK", new OnClickListener() {

		public void onClick(DialogInterface arg0, int arg1) {
			myLooper.quit();
			arg0.dismiss();
		}
	});

	builder.create().show();
	Looper.loop();
}

public static void showOkDialog(Activity context, String msg, final OnClickListener listener) {
	Looper.prepare();
	final Looper myLooper = Looper.myLooper();

	final AlertDialog.Builder builder = new AlertDialog.Builder(context);
	builder.setMessage(msg).setNeutralButton("OK", new OnClickListener() {

		public void onClick(DialogInterface arg0, int arg1) {
			listener.onClick(arg0, arg1);
			myLooper.quit();
			arg0.dismiss();
		}
	});

	builder.create().show();
	Looper.loop();
}

public static void showSimNaoDialog(Activity context, String msg, final OnClickListener listenerSim) {
	Looper.prepare();
	final Looper myLooper = Looper.myLooper();

	AlertDialog.Builder builder = new AlertDialog.Builder(context);
	builder.setMessage(msg).setPositiveButton("Sim", new OnClickListener() {

		public void onClick(DialogInterface arg0, int arg1) {
			listenerSim.onClick(arg0, arg1);
			myLooper.quit();
			arg0.dismiss();
		}
	}).setNegativeButton("Não", new OnClickListener() {

		public void onClick(DialogInterface arg0, int arg1) {
			myLooper.quit();
			arg0.dismiss();
		}
	});
	builder.create().show();
	Looper.loop();
}

}
[/code]

O problema é que, se eu chamo uma Dialog na minha activity, e depois chamo outra, com outra msg, dá o seguinte erro:

FATAL EXCEPTION: Thread-8
java.lang.RuntimeException: Only one Looper may be created per thread
    at android.os.Looper.prepare
    at br.com.tdta.service.view.MessageDialog.showOkDialog
    at br.com.tdta.service.view.AtualizaDados.atualizaDados
    at br.com.tdta.service.view.AtualizaDados.access$000
    at br.com.tdta.service.view.AtualizaDados$1.run
    at java.lang.Thread.run

Se eu tirar o Looper.prepare(), cai em outra exception, dizendo que TEM que ter esse Looper.prepare(). Agora não sei mais o que fazer.

Não tem outra solução sem o Looper?

Aliás, olhando na documentação da classe Looper:
http://developer.android.com/reference/android/os/Looper.html

Ele só usa Looper.prepare() e Looper.loop() depois.

Não consegui nenhuma solução sem o Looper…

[quote=Marky.Vasconcelos]Aliás, olhando na documentação da classe Looper:
http://developer.android.com/reference/android/os/Looper.html

Ele só usa Looper.prepare() e Looper.loop() depois.[/quote]
Sobre a documentação:

[quote]public static final void prepare ()

Initialize the current thread as a looper. This gives you a chance to create handlers that then reference this looper, before actually starting the loop. Be sure to call loop() after calling this method, and end it by calling quit().[/quote]

Na documentação do método prepare(), ele pede pra encerrar usando o método quit().
Vou tentar sem o quit() aqui…

[quote=Marky.Vasconcelos]Aliás, olhando na documentação da classe Looper:
http://developer.android.com/reference/android/os/Looper.html

Ele só usa Looper.prepare() e Looper.loop() depois.[/quote]

testei aqui sem o quit(). Se eu não usa-lo, a aplicação fica numa espécie de loop infinito.

Resolvi assim:

Apaguei aquela classe que mostrava as caixinhas de dialogo. Ao invés de ter uma classe estática, toda vez que eu preciso de um Dialog, eu faço isso:

Looper.prepare();
new AlertDialog.Builder(this).setMessage("Ocorreu um erro ao conectar no servidor").setNeutralButton("OK", new AlertDialog.OnClickListener() {

	public void onClick(DialogInterface arg0, int arg1) {
		Looper.myLooper().quit();
	}
}).create().show();
Looper.loop();

Caso dê o erro Only one looper may be created per thread, eu tiro os Looper, assim:

new AlertDialog.Builder(InformaIP.this).setMessage("Ocorreu um erro ao conectar no servidor").setNeutralButton("OK", new AlertDialog.OnClickListener() {

	public void onClick(DialogInterface arg0, int arg1) {
		//
	}
}).create().show();

É triste, mas foi com essa POG que eu estou seguindo com o projeto.
Por favor, caso alguém tenha uma solução melhor, posta aqui.

Fiz a POG numa classe separada, usando uns IF…

[code]import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Looper;

/**
*

  • @author eliangela
    */
    public class MessageDialog {

    private static boolean erro = false;

    public static void showOkDialog(Activity act, String msg) {
    try {
    Looper.prepare();
    } catch (Exception e) {
    erro = true;
    }
    new AlertDialog.Builder(act).setMessage(msg).
    setNeutralButton(“OK”, new AlertDialog.OnClickListener() {

     	public void onClick(DialogInterface arg0, int arg1) {
     		if (!erro) {
     			Looper.myLooper().quit();
     		}
    
     		erro = false;
     	}
     }).create().show();
     if (!erro) {
     	Looper.loop();
     }
    

    }

    public static void showOkDialog(Activity act, String msg, final OnClickListener listener) {
    try {
    Looper.prepare();
    } catch (Exception e) {
    erro = true;
    }
    new AlertDialog.Builder(act).setMessage(msg).
    setNeutralButton(“OK”, new OnClickListener() {

     	public void onClick(DialogInterface arg0, int arg1) {
     		listener.onClick(arg0, arg1);
     		if (!erro) {
     			Looper.myLooper().quit();
     		}
    
     		erro = false;
     	}
     }).create().show();
     if (!erro) {
     	Looper.loop();
     }
    

    }

    public static void showSimNaoDialog(Activity act, String msg, final OnClickListener listenerSim) {
    try {
    Looper.prepare();
    } catch (Exception e) {
    erro = true;
    }
    new AlertDialog.Builder(act).setMessage(msg).
    setPositiveButton(“Sim”, new OnClickListener() {

     	public void onClick(DialogInterface arg0, int arg1) {
     		listenerSim.onClick(arg0, arg1);
     		if (!erro) {
     			Looper.myLooper().quit();
     		}
    
     		erro = false;
     	}
     }).setNegativeButton("Não", new OnClickListener() {
    
     	public void onClick(DialogInterface arg0, int arg1) {
     		if (!erro) {
     			Looper.myLooper().quit();
     		}
    
     		erro = false;
     	}
     }).create().show();
     if (!erro) {
     	Looper.loop();
     }
    

    }
    }
    [/code]

Recaptulando: se alguem tiver uma solução melhor, por fv, poste.