1209 votes

Ne peut pas créer de gestionnaire à l'intérieur de thread qui n'a pas appelé Looper.prepare()

Quel est l'exception suivante veux dire, comment puis-je résoudre ce problème?

C'est le code:

Toast toast = Toast.makeText(mContext, "Something", Toast.LENGTH_SHORT);

C'est l'exception:

java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
     at android.os.Handler.<init>(Handler.java:121)
     at android.widget.Toast.<init>(Toast.java:68)
     at android.widget.Toast.makeText(Toast.java:231)

983voto

Jacob Marble Points 6121

Vous devez appeler Toast.makeText(...) de la thread de l'INTERFACE utilisateur:

activity.runOnUiThread(new Runnable() {
  public void run() {
    Toast.makeText(activity, "Hello", Toast.LENGTH_SHORT).show();
  }
});

C'est le copier-collé à partir d' un autre (en double) DONC réponse.

837voto

EboMike Points 39257

Vous appelez à partir d'un thread de travail. Vous devez appeler Toast.makeText() (et la plupart des autres fonctions de traiter avec l'INTERFACE utilisateur) dans le thread principal. Vous pouvez utiliser un gestionnaire, par exemple.

461voto

mjosh Points 4015

Je sais que je suis un peu en retard mais voilà. Android fonctionne essentiellement sur deux types de filetage à savoir le thread de l'INTERFACE utilisateur et le thread d'arrière-plan. Selon android documentation -

Ne pas accéder à l'INTERFACE utilisateur Android toolkit de l'extérieur de la thread d'INTERFACE utilisateur pour résoudre ce problème, Android offre plusieurs moyens d'accéder au thread de l'INTERFACE utilisateur à partir d'autres threads. Voici une liste de méthodes qui peuvent aider:

Activity.runOnUiThread(Runnable)  
View.post(Runnable)  
View.postDelayed(Runnable, long)

Maintenant, il existe différentes méthodes pour résoudre ce problème. Je vais l'expliquer par un exemple de code

runOnUiThread

new Thread()
{
    public void run()
    {
        myactivity.this.runOnUiThread(new runnable()
        {
            public void run()
            {
                //Do your UI operations like dialog opening or Toast here
            }
        });
    }
}.start();

LOOPER

Classe utilisée pour exécuter une boucle de message pour un thread. Threads par défaut ne pas une boucle de message qui leur sont associés, pour en créer un, appel prepare() dans le thread qui est l'exécution de la boucle, puis la boucle() à ont-il traiter les messages jusqu'à ce que la boucle est arrêté.

class LooperThread extends Thread {
    public Handler mHandler;

    public void run() {
        Looper.prepare();

        mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
    }
}

AsyncTask

AsyncTask vous permet d'effectuer un travail asynchrone sur votre utilisateur de l'interface. Il effectue les opérations de blocage dans un thread de travail et puis publie les résultats sur le thread de l'INTERFACE utilisateur, sans vous obliger à poignée de fils et/ou les gestionnaires de vous-même.

public void onClick(View v) {
    new CustomTask().execute((Void[])null);
}


private class CustomTask extends AsyncTask<Void, Void, Void> {

    protected Void doInBackground(Void... param) {
        //Do some work
        return null;
    }

    protected void onPostExecute(Void param) {
        //Print Toast or open dialog
    }
}

Gestionnaire

Un Gestionnaire vous permet d'envoyer et de traiter le Message et Praticable objets associé à un thread MessageQueue.

Message msg = new Message();


new Thread()
{
    public void run()
    {
        msg.arg1=1;
        handler.sendMessage(msg);
    }
}.start();



Handler handler = new Handler(new Handler.Callback() {

    @Override
    public boolean handleMessage(Message msg) {
        if(msg.arg1==1)
        {
            //Print Toast or open dialog        
        }
        return false;
    }
});

99voto

Khulja Sim Sim Points 460

Essayez cela, quand vous voyez les runtimeException en raison de l'Arpenteuse de ne pas être préparé avant de gestionnaire.

Handler handler = new Handler(Looper.getMainLooper()); 

handler.postDelayed(new Runnable() {
  @override
  void run() {
  // Run your task here
  }
}, 1000 );

44voto

ChicoBird Points 251

J'ai rencontré le même problème, et voici comment je l'ai résolu:

private final class UIHandler extends Handler
{
    public static final int DISPLAY_UI_TOAST = 0;
    public static final int DISPLAY_UI_DIALOG = 1;

    public UIHandler(Looper looper)
    {
        super(looper);
    }

    @Override
    public void handleMessage(Message msg)
    {
        switch(msg.what)
        {
        case UIHandler.DISPLAY_UI_TOAST:
        {
            Context context = getApplicationContext();
            Toast t = Toast.makeText(context, (String)msg.obj, Toast.LENGTH_LONG);
            t.show();
        }
        case UIHandler.DISPLAY_UI_DIALOG:
            //TBD
        default:
            break;
        }
    }
}

protected void handleUIRequest(String message)
{
    Message msg = uiHandler.obtainMessage(UIHandler.DISPLAY_UI_TOAST);
    msg.obj = message;
    uiHandler.sendMessage(msg);
}

Pour créer le UIHandler, vous devez effectuer les opérations suivantes:

    HandlerThread uiThread = new HandlerThread("UIHandler");
    uiThread.start();
    uiHandler = new UIHandler((HandlerThread) uiThread.getLooper());

Espérons que cette aide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X