2012-08-13 8 views
19

Ho creato un caricamento immagine asynctask basato su una funzione. E dopo il caricamento, ottengo questo errore su onPostExecute. Ho letto alcune risposte Stackoverflow su Runnable, ma ho continuato a ricevere l'errore ancora e ancora nonostante l'implementazione di una soluzione diversa.AsyncTask Android [Impossibile creare il gestore all'interno del thread che non ha chiamato Looper.prepare()]

Il mio codice:

class uploadFile extends AsyncTask<String, String, String> { 
     private ProgressDialog pDialog; 

     /** 
     * -------------------------------------------------------------------- 
     * --------------------------------- Before starting background thread 
     * Show Progress Dialog 
     * */ 
     @Override 
     protected void onPreExecute() { 
      super.onPreExecute(); 
      pDialog = new ProgressDialog(MainActivity.this); 
      pDialog.setMessage("Uploading file"); 
      pDialog.setIndeterminate(false); 
      pDialog.setCancelable(false); 
      pDialog.show(); 
     } 

     /** 
     * -------------------------------------------------------------------- 
     * --------------------------------- getting all recent articles and 
     * showing them in listview 
     * */ 
     @Override 
     protected String doInBackground(String... args) { 
      HttpURLConnection conn = null; 
      DataOutputStream dos = null; 
      DataInputStream inStream = null; 
      String existingFileName = Environment.getExternalStorageDirectory() 
        .getAbsolutePath() + "/mypic.png"; 
      String lineEnd = "\r\n"; 
      String twoHyphens = "--"; 
      String boundary = "*****"; 
      int bytesRead, bytesAvailable, bufferSize; 
      byte[] buffer; 
      int maxBufferSize = 1 * 1024 * 1024; 
      String serverResponseMessage = ""; 
      String urlString = "http://google.info/imgupl/index.php"; 
      try { 
       // ------------------ CLIENT REQUEST 
       FileInputStream fileInputStream = new FileInputStream(new File(
         existingFileName)); 
       // open a URL connection to the Servlet 
       URL url = new URL(urlString); 
       // Open a HTTP connection to the URL 
       conn = (HttpURLConnection) url.openConnection(); 
       // Allow Inputs 
       conn.setDoInput(true); 
       // Allow Outputs 
       conn.setDoOutput(true); 
       // Don't use a cached copy. 
       conn.setUseCaches(false); 
       // Use a post method. 
       conn.setRequestMethod("POST"); 
       conn.setRequestProperty("Connection", "Keep-Alive"); 
       conn.setRequestProperty("Content-Type", 
         "multipart/form-data;boundary=" + boundary); 
       dos = new DataOutputStream(conn.getOutputStream()); 
       dos.writeBytes(twoHyphens + boundary + lineEnd); 
       dos.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\"" 
         + existingFileName + "\"" + lineEnd); 
       dos.writeBytes(lineEnd); 
       // create a buffer of maximum size 
       bytesAvailable = fileInputStream.available(); 
       bufferSize = Math.min(bytesAvailable, maxBufferSize); 
       buffer = new byte[bufferSize]; 
       // read file and write it into form... 
       bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
       while (bytesRead > 0) { 
        dos.write(buffer, 0, bufferSize); 
        bytesAvailable = fileInputStream.available(); 
        bufferSize = Math.min(bytesAvailable, maxBufferSize); 
        bytesRead = fileInputStream.read(buffer, 0, bufferSize); 
       } 
       // send multipart form data necesssary after file data... 
       dos.writeBytes(lineEnd); 
       dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd); 
       // close streams 
       Integer serverResponseCode = conn.getResponseCode(); 
       serverResponseMessage = conn.getResponseMessage(); 
       Toast.makeText(getApplicationContext(), serverResponseMessage, 
         Toast.LENGTH_SHORT).show(); 
       Toast.makeText(getApplicationContext(), 
         serverResponseCode.toString(), Toast.LENGTH_SHORT) 
         .show(); 
       Log.e("Debug", "File is written"); 
       fileInputStream.close(); 
       dos.flush(); 
       dos.close(); 
      } catch (MalformedURLException ex) { 
       Log.e("Debug", "error: " + ex.getMessage(), ex); 
      } catch (IOException ioe) { 
       Log.e("Debug", "error: " + ioe.getMessage(), ioe); 
      } 
      // ------------------ read the SERVER RESPONSE 
      try { 
       inStream = new DataInputStream(conn.getInputStream()); 

       while ((str = inStream.readLine()) != null) { 
        Log.e("Debug", "Server Response " + str); 
       } 
       inStream.close(); 

      } catch (IOException ioex) { 
       Log.e("Debug", "error: " + ioex.getMessage(), ioex); 
      } 
      return null; 
     } 

     /** 
     * -------------------------------------------------------------------- 
     * --------------------------------- After completing background task 
     * Dismiss the progress dialog 
     * **/ 
     protected void onPostExecute(String args) { 
      // dismiss the dialog after getting all products 
      pDialog.dismiss(); 
      MainActivity.this.runOnUiThread(new Runnable() { 
        public void run() { 
        Toast.makeText(MainActivity.this, "Hello", Toast.LENGTH_SHORT).show(); 
        } 
       }); 

     } 
    } 

mio logcat:

08-13 22:13:32.627: E/AndroidRuntime(9554): FATAL EXCEPTION: AsyncTask #1 
08-13 22:13:32.627: E/AndroidRuntime(9554): java.lang.RuntimeException: An error occured while executing doInBackground() 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at android.os.AsyncTask$3.done(AsyncTask.java:200) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.lang.Thread.run(Thread.java:1019) 
08-13 22:13:32.627: E/AndroidRuntime(9554): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at android.os.Handler.<init>(Handler.java:121) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at android.widget.Toast.<init>(Toast.java:68) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at android.widget.Toast.makeText(Toast.java:231) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at dev.google.imageupload.MainActivity$uploadFile.doInBackground(MainActivity.java:128) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at dev.google.imageupload.MainActivity$uploadFile.doInBackground(MainActivity.java:1) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at android.os.AsyncTask$2.call(AsyncTask.java:185) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
08-13 22:13:32.627: E/AndroidRuntime(9554):  ... 4 more 

modificato dopo il suggerimento di zapl:

08-13 22:38:06.297: E/AndroidRuntime(11511): FATAL EXCEPTION: AsyncTask #1 
08-13 22:38:06.297: E/AndroidRuntime(11511): java.lang.RuntimeException: An error occured while executing doInBackground() 
08-13 22:38:06.297: E/AndroidRuntime(11511): at android.os.AsyncTask$3.done(AsyncTask.java:200) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.lang.Thread.run(Thread.java:1019) 
08-13 22:38:06.297: E/AndroidRuntime(11511): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 
08-13 22:38:06.297: E/AndroidRuntime(11511): at android.os.Handler.<init>(Handler.java:121) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at android.widget.Toast.<init>(Toast.java:68) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at android.widget.Toast.makeText(Toast.java:231) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at dev.google.imageupload.MainActivity$uploadFile.doInBackground(MainActivity.java:128) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at dev.google.imageupload.MainActivity$uploadFile.doInBackground(MainActivity.java:1) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at android.os.AsyncTask$2.call(AsyncTask.java:185) 
08-13 22:38:06.297: E/AndroidRuntime(11511): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
08-13 22:38:06.297: E/AndroidRuntime(11511): ... 4 more 
+4

è sufficiente creare il 'Toast' direttamente in' onPostExecute' poiché è già stato eseguito sul thread dell'interfaccia utente. 'AsyncTask's può essere eseguito solo dal thread dell'interfaccia utente e quei metodi' onSomthing' verranno richiamati dal thread dell'interfaccia utente – zapl

+0

Rimuovi runOnUiThread e questo ha causato un altro problema :( – MrYanDao

+0

Condividi il nuovo problema: D. E lasciami anche knw cosa vuoi fare dopo aver caricato la tua foto –

risposta

44

Si sta tentando di aggiornare l'interfaccia utente da un thread in background. O spostare il brindisi su onPostExecute, che viene eseguito sul thread dell'interfaccia utente (consigliato) o chiamare runOnUiThread.

runOnUiThread(new Runnable() { 
    public void run() { 
     // runs on UI thread 
    } 
}); 
+0

Ho già avuto questo sul mio onPostExecute. – MrYanDao

+3

Corretto (che non è necessario), ma sono presenti anche due chiamate 'Toast' in' doInBackground', che causa l'eccezione. –

+0

Quindi intendi dire che non posso avere un 'Toast' in' doInBackground'? Scusa, sono un po 'noob qui :(mi spiace! EDIT Penso di aver capito, aspetta un momento .. – MrYanDao

6

a dev.shaunidiot.imageupload.MainActivity $ uploadFile.doInBackground (MainActivity.java:128)

è possibile utilizzare il meccanismo di avanzamento di AsyncTask s per aggiornare UI dall'interno doInBackground mentre l'attività è in esecuzione:

sostituire

Toast.makeText(getApplicationContext(), serverResponseMessage, 
     Toast.LENGTH_SHORT).show(); 
Toast.makeText(getApplicationContext(), 
     serverResponseCode.toString(), Toast.LENGTH_SHORT) 
     .show(); 

in doInBackground con

publishProgress(serverResponseMessage, serverResponseCode.toString()); 

e aggiungere quanto segue al vostro AsyncTask implementazione

@Override 
protected void onProgressUpdate(String... values) { 
    if (values != null) { 
     for (String value : values) { 
      // shows a toast for every value we get 
      Toast.makeText(MainActivity.this, value, Toast.LENGTH_SHORT).show(); 
     } 
    } 
} 

È già stato impostato String come tipo di progresso nella AsyncTask<Params, Progress, Result> così nel caso in cui si desidera utilizzare il progresso per qualcosa di diverso è possibile prova ad usare runOnUiThread ma non so se funzionerà.

Problemi correlati