Java Не могу создать обработчик внутри потока, который не вызвал Looper.prepare ()

Я видел большинство связанных вопросов, но не смог найти ни одного, который бы решал мою проблему.

Это мой код, и я понятия не имею, что я делаю неправильно.

<code>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;
    }
}
</code>

Это вложено в оператор if, который находится в статическом классе & apos; Функция конструктора и статический класс находятся в публичном классе, который расширяет ListActivity. Я новичок в Java.

Ошибка:

<code>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
</code>

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

Ответы на вопрос(3)

Handler в основном это класс обратного вызова, который Android использует для асинхронного запуска кода, когда вы отправляете ему сообщения какой-либо формы. Для того, чтобыHandler чтобы получать и обрабатывать сообщения в отдельном потоке от потока пользовательского интерфейса, он должен держать поток открытым. Вот гдеLooper класс входит. Как в примере страницы, вызовLooper.prepare() на вершинеrun() метод, затем вызвать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();

Всякий раз, когда вы хотите, чтобы нить умерла. Это обычно вonPause(), onStop(), или жеonDestroy() методы деятельности.

Обратите внимание, что нить такого родаwill stay open when the activity is closed so you must kill it before the user quits.

поскольку он готовит петлитель для вас.

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

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

ВАШ ОТВЕТ НА ВОПРОС