Problema con Toast in AsyncTask chiamata al metodo

Ciao A Tutti,
Ho un AsyncTask che post un po ‘ di dati a un server. Lo fa chiamando un metodo statico che ho scritto da doInBackground. Quando ho eseguito l’AsyncTask, io mando il contesto dell’attività che ha chiamato execute(), che vi invio il mio metodo statico, perché ne ha bisogno per fare un Brindisi se qualcosa va storto durante la conversazione con il server. Tuttavia, ottengo questo errore quando il Toast è fatto nel metodo statico:

04-21 12:49:16.689: ERROR/AndroidRuntime(2123): FATAL EXCEPTION: AsyncTask #1
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): java.lang.RuntimeException: An error occured   while executing doInBackground()
04-21 12:49:16.689: ERROR/AndroidRuntime(2123):at android.os.AsyncTask$3.done(AsyncTask.java:200)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask.setException(FutureTask.java:125)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.lang.Thread.run(Thread.java:1019)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.os.Handler.<init>(Handler.java:121)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.widget.Toast.<init>(Toast.java:68)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.widget.Toast.makeText(Toast.java:23
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.util.ServerConnections.PostToLoginPage(ServerConnections.java:36)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.Whiteboard.WhiteboardLogin$LoginTask.doInBackground(WhiteboardLogin.java:150)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at com.microogle.dev.Whiteboard.WhiteboardLogin$LoginTask.doInBackground(WhiteboardLogin.java:1)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
04-21 12:49:16.689: ERROR/AndroidRuntime(2123): ... 4 more

Che è seguita da una fuoriuscita finestra di errore. Sto assumendo questo è a causa di un errore con il contesto passato a Brindisi nel metodo statico. AsyncTask è:

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

    private WhiteboardLogin activity;
    private Context callingContext;
    private ProgressDialog dialog;
    private String user, pass;
    private boolean sendIntent = true, loginError = false, populateError = false;

    public LoginTask(WhiteboardLogin activity, String user, String pass, Context callingContext){
        this.activity = activity;
        this.user = user.trim();
        this.pass = pass.trim();
        this.callingContext = callingContext;
    }
@Override
    protected Void doInBackground(Void... params) {
        ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
        nameValuePairs.add(new BasicNameValuePair("user",user));
        nameValuePairs.add(new BasicNameValuePair("pass",pass));
        sessionUser = user;
        sessionPassword = pass;
        //Posts the username and password to the login page and toasts an error if the login doesn't work 
        if(ServerConnections.PostToLoginPage(callingContext, nameValuePairs, activity.getString(R.string.loginPageURI)) == 1){
            dialog.dismiss();
            sendIntent = false;
            loginError = true;
            publishProgress();
           return null;
        }
        else{
           userDataList = populateUserDataList(callingContext, user,pass);
           if(userDataList == null){
               dialog.dismiss();
               sendIntent = false;
               populateError = true;
               return null;
           }
       }
       return null;
    }

OriginaleL’autore Eliezer | 2011-04-21

4 Replies
  1. 22

    Il codice nel doInBackground() metodo viene eseguito sul proprio thread così non si può accedere a qualsiasi elemento dell’interfaccia utente da lì direttamente sono in esecuzione sul thread UI.

    Quindi hai due opzioni.

    1. Gestire tutte le UI roba in onPreExecute() e onPostExecute() metodo che viene eseguito nel thread dell’interfaccia utente.

    2. Gestire UI roba in onProgressUpdate() metodo che gira anche sul thread UI. È anche possibile attivare questo metodo all’interno di doInBackground() chiamando publishProgress().

    Anche se io mando il thread dell’interfaccia utente del contesto?
    Sì, anche allora.

    OriginaleL’autore Flo

  2. 2

    si può Brindare all’interno di doInBackground

    utilizzare questo codice

    runOnUiThread(new Runnable() {
    public void run() {
    
        Toast.makeText(<your class name>.this, "Cool Ha?", Toast.LENGTH_SHORT).show();
        }
    });

    OriginaleL’autore Jack K Fouani

  3. 1

    Si sta tentando di aggiornare l’interfaccia utente all’interno di doInBackground() che corre in un altro thread diverso dal thread dell’interfaccia utente.
    Si dovrebbe visualizzare il Brindisi in onPostExecute() metodo sul AsyncTask: http://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute(Risultato)

    Ci sono altri Toast che sto visualizzando in onPostExecute() ma quelli che stanno causando i problemi sono in un metodo in una classe diversa, la riceve una chiamata mentre in doInBackground() quindi non sono in grado di mettere in onPostExecute()
    Penso che avete bisogno di lavorare sulla vostra logica, che il metodo statico non dovrebbe visualizzare un Toast. Comunque, puoi fare quello che vuoi utilizzando un Gestore, invece, il contesto, la creazione di un gestore, nella sua Attività, e poi lo trasmette al metodo statico. Quando necessario, inviare un eseguibile che visualizza il Brindisi al gestore
    Mi è stato effettivamente solo utilizzando il Brindisi per il debug (probabilmente dovrebbe utilizzare il Log però), ho solo pensato che sarebbe meglio per me sapere se si fa qualcosa di simile a questo è stato possibile.
    Ah ok, sì, è più sicuro utilizzare solo Registro per scopi di debug 🙂

    OriginaleL’autore aromero

  4. 0

    Sì utilizzo di un registro per il debug è più semplice, tuttavia, se si dispone di messaggi che devono essere visualizzati durante l’elaborazione in background per qualsiasi motivo, è possibile utilizzare il
    onProgressUpdate() il metodo, come osservato in precedenza da Flo. È anche possibile attivare questo metodo ogni volta che avete bisogno di scrivere un messaggio, chiamando publishProgress() all’interno di DoInBackground(). Il contenuto del messaggio o la lavorazione stati possono essere trasferiti facilmente tramite variabili private in un ASyncTask che sono accessibili sia per lo Sfondo e il metodo di UI metodi.

    OriginaleL’autore Jesse Finnerty

Lascia un commento