3

関連する質問のほとんどを見ましたが、問題を解決するものは見つかりませんでした。

これは私のコードであり、何が間違っているのかわかりません。

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

これは、静的クラスのコンストラクター関数にある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はfinal Handler handler = new Handler() {

4

3 に答える 3

9

AHandlerは基本的に、Androidが何らかの形式のメッセージを送信するときにコードを非同期的に実行するために使用するコールバッククラスです。がUIスレッドとは別のスレッドでメッセージを受信して​​処理するHandlerには、スレッドを開いたままにしておく必要があります。そこでLooperクラスが登場します。ページの例のように、メソッドLooper.prepare()の上部で呼び出してから、下部で呼び出します。スレッドは、明示的に破棄するまで開いたままになります。スレッドを破棄するには、クラスにを呼び出すメソッドが必要です。run()Looper.loop()LooperThreadLooper.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()

この種のスレッドは、アクティビティが閉じられても開いたままになるため、ユーザーが終了する前にスレッドを強制終了する必要があることに注意してください。

于 2012-05-01T20:46:13.997 に答える
2

UIスレッドで指定されたアクションを実行します

 ActivityName.runOnUiThread(new Runnable() {
 public void run()
    {
     //put your logic here
    }
 });
于 2013-02-27T07:04:10.733 に答える
1

ルーパーを準備するため、HandlerThreadを使用することをお勧めします。

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

于 2012-05-01T20:47:41.650 に答える