2012-05-01 88 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

您尚未分享代碼的相關部分。發佈嵌套在'FileTransferActivity'中的'NamedFile'構造函數的代碼。尤其是第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

我怎樣才能發送消息到主線程?那麼我怎樣才能調用這個方法'sendThumbnail(path,buffer);'在FileTransferActivity類中定義爲靜態方法,並引用FileTransferActivity類中定義的靜態變量(也)? – 19greg96

+0

處理程序處理它們在其中創建的任何線程中的消息。如果您希望處理程序在主線程中處理消息,請在主線程中創建處理程序。然後將消息從線程傳遞給它。 – DeeV

+0

感謝這個一百萬 - 完整的救星 – wirbly

2

運行UI線程

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