Java无法在未调用Looper.prepare()的线程内创建处理程序

我看到了大部分相关问题,但我找不到任何解决问题的方法。

这是我的代码,我不知道我做错了什么。

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 m = ((HashMap)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 msg = new HashMap(); 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; } } 

它嵌套在静态类的构造函数中的if语句中,静态类位于扩展ListActivity的公共类中。 我是Java的新手。

错误:

 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.(Handler.java:121) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile$1.(FileTransferActivity.java:588) 05-01 20:21:58.830: E/AndroidRuntime(584): at greg.projects.FileTransfer.FileTransferActivity$NamedFile.(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是final Handler handler = new Handler() {

Handler基本上是一个回调类,当你向它发送某种forms的消息时,Android会用它来异步运行代码。 为了使Handler能够在UI线程的单独线程中接收和处理消息,它必须保持线程打开。 这就是Looper类的用武之地。就像在页面示例中一样,在run()方法的顶部调用Looper.loop() ,然后在底部调用Looper.loop() 。 线程将保持打开状态,直到您明确销毁它为止。 为了销毁Looper线程,你必须在Thread类中有一个调用Looper.getMyLooper().quit()

一个示例线程类将是这样的:

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

通过创建一个新对象来正常运行该线程。

 LooperThread myLooperThread = new LooperThread(); 

保持对它的引用。 然后打电话:

 myLooperThread.killMe(); 

每当你想要线程死亡。 这通常位于Activity的onPause()onStop()onDestroy()方法中。

请注意, 当活动关闭时 ,这种性质的线程将保持打开状态,因此您必须在用户退出之前将其终止

在UI线程上运行指定的操作

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

我建议使用HandlerThread,因为它为你准备了looper。

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