2012-05-01 11 views
3

ほとんどの関連する質問が表示されましたが、私の問題は解決されませんでした。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<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; 
    } 
} 

これは静的クラスのコンストラクタ関数であると静的クラスがListActivityを拡張するパブリッククラスであるif文の中にネストされています。私は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() {ある)

+0

あなたはどのようなエラーを得ているを実行しますか? – Charles

+0

質問に追加しました。 – 19greg96

+0

コードの関連部分を共有していません。 'NamedFile'のコンストラクタのコードを' FileTransferActivity'にネストしてください。特に588行目の 'FileTransferActivity' –

答えて

9

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

スレッドを終了させるときはいつでも、これは通常、アクティビティのonPause()onStop()、またはonDestroy()のメソッドにあります。

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

+0

どうすればメインスレッドにメッセージを送ることができますか?では、FileTransferActivityクラスで静的メソッドとして定義され、FileTransferActivityクラスで定義された静的変数を参照するこのメソッド(sendThumbnail(path、buffer);)をどのように呼び出すことができますか? – 19greg96

+0

ハンドラは、作成されたどのスレッドでもメッセージを処理します。ハンドラでメインスレッドのメッセージを処理する場合は、メインスレッドでハンドラを作成します。その後、スレッドからメッセージを渡します。 – DeeV

+0

この完全なライフセーバーのおかげで – wirbly

2

UIスレッド上で、指定されたアクション

ActivityName.runOnUiThread(new Runnable() { 
public void run() 
    { 
    //put your logic here 
    } 
}); 
関連する問題