2012-08-13 19 views
19

He creado una carga de imágenes asynctask basada en una función. Y después de subir, aparece este error en PostExecute. Leí algunas respuestas de Stackoverflow en Runnable pero seguí recibiendo el error una y otra vez a pesar de implementar una solución diferente.Android AsyncTask [No se puede crear el controlador dentro del hilo que no ha llamado a Looper.prepare()]

Mi código:

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(); 
        } 
       }); 

     } 
    } 

Mi 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 

editar después de la sugerencia de 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

simplemente crea el 'Toast' directamente en' onPostExecute' ya que eso ya se ejecutó en el hilo de la interfaz de usuario. 'AsyncTask's solo se puede ejecutar desde el subproceso UI y los métodos' onSomthing' se invocarán desde el subproceso UI nuevamente – zapl

+0

Eliminar el runOnUiThread y eso causó otro problema :( – MrYanDao

+0

Comparta el nuevo problema: D. Y también déjeme saber ¿Qué quieres hacer después de que tu foto sea cargada? –

Respuesta

44

Usted está intentando actualizar la interfaz de usuario desde un subproceso en segundo plano. Mueva la tostada al onPostExecute, que se ejecuta en el subproceso de la interfaz de usuario (recomendado) o llame al runOnUiThread.

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

Ya tuve esto en mi onPostExecute. – MrYanDao

+3

Correcto (lo cual no es necesario), pero tiene dos llamadas 'Toast' en' doInBackground' también, que está causando la excepción. –

+0

¿Quiere decir que no puedo tener un 'Toast' en' doInBackground'? Lo siento, soy un poco novato aquí :(lo siento! EDITAR Creo que lo entiendo, espera un momento ... – MrYanDao

6

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

podría utilizar el mecanismo de avance de AsyncTask s para actualizar la interfaz de usuario desde el interior, mientras que doInBackground la tarea se está ejecutando:

reemplazar

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

en doInBackground con

publishProgress(serverResponseMessage, serverResponseCode.toString()); 

y añadir lo siguiente a su aplicación AsyncTask

@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(); 
     } 
    } 
} 

Usted ya ha configurado String como tipo de avance en AsyncTask<Params, Progress, Result> por lo que en caso de que quiera utilizar el progreso de algo diferente que pueda intente usar runOnUiThread pero no sé si eso funcionará.

Cuestiones relacionadas