Java无法在未调用Looper.prepare()的线程内创建处理程序
发布时间:2020-12-15 04:57:32 所属栏目:Java 来源:网络整理
导读:我看到了大部分相关问题,但我找不到任何解决问题的方法. 这是我的代码,我不知道我做错了什么. static class NamedFile { public File f; public String name; public String ext; public String path; public BitmapDrawable icon; public NamedFile (File f
我看到了大部分相关问题,但我找不到任何解决问题的方法.
这是我的代码,我不知道我做错了什么. 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,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,false)); } }*/ if (ext != null && (ext.equals("jpeg") || ext.equals("jpg") || ext.equals("bmp") || ext.equals("gif") || ext.equals("png"))) { /* Bitmap b = BitmapFactory.decodeFile(path,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,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; } } 它嵌套在静态类的构造函数中的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.<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是最终的Handler处理程序= new Handler(){) 解决方法
Handler基本上是一个回调类,当你向它发送某种形式的消息时,Android会用它来异步运行代码.为了使Handler能够在UI线程的单独线程中接收和处理消息,它必须保持线程打开.这就是
Looper类的用武之地.就像在页面示例中一样,在run()方法的顶部调用Looper.prepare(),然后在底部调用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()方法中. 请注意,当活动关闭时,这种性质的线程将保持打开状态,因此您必须在用户退出之前将其终止. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |