Java No se puede crear el controlador dentro del subproceso que no ha llamado Looper.prepare ()

Vi la mayoría de las preguntas relacionadas, pero no pude encontrar ninguna que solucionara mi problema.

Este es mi código, y no tengo ni idea de lo que estoy haciendo mal.

static class NamedFile { public File f; public String name; public String ext; public String path; public BitmapDrawable icon; public NamedFile (File file) { f = file; name = f.getName(); if (f.isFile()) { if (name.indexOf('.') != -1) { ext = name.substring(name.lastIndexOf('.') + 1).trim().toLowerCase(); } else { ext = "unknown"; } } path = f.getAbsolutePath(); if (ext == null) { icon = mFolderIcon; } else { BitmapDrawable i = icons.get(ext); if (i == null) { try { int rid = R.drawable.class.getField(ext).getInt(R.drawable.class); icons.put(ext, new BitmapDrawable(Bitmap.createScaledBitmap(BitmapFactory.decodeResource(res, rid, mOpts), iconSize, iconSize, false))); icon = icons.get(ext); } catch (Exception e1) {} } else { icon = i; } }/* else if (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("bmp") || ext.equals("gif") || ext.equals("png")) { Bitmap b = BitmapFactory.decodeFile(path, mOpts); if (b != null) { icon = new BitmapDrawable(Bitmap.createScaledBitmap(b, iconSize, iconSize, false)); } }*/ if (ext != null && (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("bmp") || ext.equals("gif") || ext.equals("png"))) { /* Bitmap b = BitmapFactory.decodeFile(path, mOpts); if (b != null) { icon = new BitmapDrawable(Bitmap.createScaledBitmap(b, iconSize, iconSize, false)); } */ final Handler handler = new Handler() { @Override public void handleMessage(Message message) { HashMap<String, Object> m = ((HashMap<String, Object>)message.obj); sendThumbnail ((String)m.get("path"), (byte[])m.get("data")); } }; Thread thread = new Thread() { public void writeInt (byte[] buff, int pos, int value) { buff[pos] = (byte)(value >>> 24); buff[pos + 1] = (byte)(value >>> 16); buff[pos + 2] = (byte)(value >>> 8); buff[pos + 3] = (byte)value; } @Override public void run() { try { Bitmap b = BitmapFactory.decodeFile(path, mOpts); if (b.getHeight() > 256 || b.getWidth() > 256) { float r; if (b.getHeight() > b.getWidth()) { r = 128f / b.getHeight(); } else { r = 128f / b.getWidth(); } b = Bitmap.createScaledBitmap(b, (int)(r * b.getWidth()), (int)(r * b.getHeight()), false); byte[] buffer = new byte[b.getWidth() * b.getHeight() * 4 + 8]; writeInt (buffer, 0, b.getWidth()); writeInt (buffer, 4, b.getHeight()); int i = 8; for (int y = 0; y < b.getHeight(); y ++) { for (int x = 0; x < b.getWidth(); x ++) { writeInt (buffer, i, b.getPixel(x, y)); i += 4; } } HashMap<String, Object> msg = new HashMap<String, Object>(); msg.put("path", path); msg.put("data", buffer); Message message = handler.obtainMessage(1, msg); handler.sendMessage(message); } } catch (Exception e) { sendLog (e.toString()); } } }; thread.start(); } if (icon == null) { icon = mFileIcon; } } public NamedFile () { } public NamedFile simpleClone () { final NamedFile nf = new NamedFile(); nf.name = name; nf.ext = ext; nf.path = path; return nf; } } 

Esto está anidado dentro de una instrucción if que está en una función de constructor de clase estática y la clase estática está en una clase pública que extiende ListActivity. Soy nuevo en Java.

Error:

 05-01 20:21:58.810: E/AndroidRuntime(584): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception 05-01 20:21:58.830: E/AndroidRuntime(584): java.lang.RuntimeException: An error occured while executing doInBackground() 05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.AsyncTask$3.done(AsyncTask.java:200) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask.run(FutureTask.java:137) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.lang.Thread.run(Thread.java:1096) 05-01 20:21:58.830: E/AndroidRuntime(584): Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.Handler.<init>(Handler.java:121) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile$1.<init>(FileTransferActivity.java:588) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile.<init>(FileTransferActivity.java:588) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$GesturesLoadTask.doInBackground(FileTransferActivity.java:489) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$GesturesLoadTask.doInBackground(FileTransferActivity.java:1) 05-01 20:21:58.830: E/AndroidRuntime(584): at android.os.AsyncTask$2.call(AsyncTask.java:185) 05-01 20:21:58.830: E/AndroidRuntime(584): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 05-01 20:21:58.830: E/AndroidRuntime(584): ... 4 more 

(FileTransferActivity.java:588 es final Handler handler = new Handler() { )

Un Handler es básicamente una clase de devolución de llamada que Android utiliza para ejecutar asincrónicamente código cuando envía mensajes de alguna forma. Para que un Handler reciba y maneje mensajes en un subproceso separado del subproceso UI, debe mantener el subproceso abierto. Aquí es donde entra en juego la clase Looper . Como en el ejemplo de la página, llame a Looper.prepare() en la parte superior del método run() , a continuación, llame a Looper.loop() en la parte inferior. El hilo permanecerá abierto hasta que explícitamente lo destruya. Para destruir un hilo Looper , debe tener un método en su clase Thread que llame a Looper.getMyLooper().quit() .

Una clase de hilo de ejemplo sería algo como esto:

 class LooperThread extends Thread { public Handler mHandler; private volatile Looper mMyLooper; public void run() { Looper.prepare(); mHandler = new Handler() { public void handleMessage(Message msg) { // process incoming messages here } }; mMyLooper = Looper.getMyLooper(); Looper.loop(); } public void killMe(){ mMyLooper.quit(); } } 

Ejecute el subproceso normalmente creando un nuevo objeto.

 LooperThread myLooperThread = new LooperThread(); 

Mantenga una referencia a ella. Luego llame:

 myLooperThread.killMe(); 

Siempre que quieras que el hilo muera. Esto suele estar en los onPause() , onStop() o onDestroy() de la Actividad.

Tenga en cuenta que un hilo de esta naturaleza permanecerá abierto cuando la actividad está cerrada por lo que debe matar antes de que el usuario se cierra .

Ejecuta la acción especificada en el subproceso de la interfaz de usuario

  ActivityName.runOnUiThread(new Runnable() { public void run() { //put your logic here } }); 

Recomiendo usar HandlerThread ya que prepara el looper para usted.

http://developer.android.com/reference/android/os/HandlerThread.html

  • ¿Cómo se puede forzar una descarga en un objeto OutputStream sin cerrarlo?
  • Set / Get Java List <> del código C
  • Actualización del proyecto de Android para utilizar Java8 (compileOptions no se puede aplicar a groovy.lang.closure)
  • Cambiar el color de fondo en touchevent en el diseño relativo
  • ¿Cómo llamar a un método cada vez que se está viendo una actividad?
  • Adición de carpetas de java al proyecto de estudio de Android
  • Cómo sincronizar datos entre dispositivos en Wi-Fi
  • ¿Está la Multicast rota para Android 2.0.1 (actualmente en el DROID) o me falta algo?
  • Algoritmo de trilateración multipunto en Java
  • ¿Qué está pasando con mi actividad de cajón de navegación de Android?
  • Java.lang.ClassCastException: org.json.simple.JSONArray no se puede convertir en org.json.JSONArray
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.