2012-08-11 60 views
0

正如你可以在標題中看到的,我試圖不用runOnUiThread每次我需要它。我解釋一下我的意思後,但首先,這裏是我當前的代碼(部分):如何*不*使用runOnUiThread

private void filePaste() 
{ 
    final File src = new File(FileClip); //Source file (as a string) 
    final File dest = new File(myPath.getText()+"/"+src.getName()); //Destination file 
    final ProgressDialog dlg = new ProgressDialog(AppContext); 

    final Thread copythread = new Thread(new Runnable() { 
    public void run() { 
     if(FileClip==null) 
     Main.this.runOnUiThread(new Runnable() { 
      public void run(){ 
      toast(getString(R.string.msg_EmptyClip)); 
      } 
     }); 
     else 
     { 
     if(src.canRead()){ 
      if(!src.isDirectory()) 
      { 
      try{ 
       BufferedInputStream in = new BufferedInputStream(new FileInputStream(src), 8192); 
       BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(dest)); 

       long pos = 0; 
       long read = 8192; 
       byte[] data = new byte[(int)read]; 

       while(pos<src.length()){ 
       int bytes = in.read(data, 0, (int)read); 
       if(bytes>-1) { 
        out.write(data,0,bytes); 
        in.skip(read); 
        in.mark((int)pos+bytes); 
        in.reset(); 
        dlg.incrementProgressBy(bytes); 
        pos+=bytes; 
       } 
       } 

       Main.this.runOnUiThread(new Runnable() { 
       public void run(){ 
        dlg.dismiss(); 
       } 
       }); 
       in.close(); 
       out.close(); 
      }catch(final Exception e) 
      { 
       Main.this.runOnUiThread(new Runnable() { 
       public void run(){ 
        alert("filePaste():\n"+e); 
       } 
       }); 
      } 

      if(Moving==true) { 
       boolean q = src.delete(); 

       if(q==true) 
       Main.this.runOnUiThread(new Runnable() { 
        public void run(){ 
        toast(getString(R.string.msg_MoveOK,src.getName())); 
        } 
       }); 
       else 
       Main.this.runOnUiThread(new Runnable() { 
        public void run(){ 
        toast(getString(R.string.msg_MoveNO,src.getName()),1); 
        } 
       }); 

       Moving = false; 
      } 
      else { 
       Main.this.runOnUiThread(new Runnable() { 
       public void run(){ 
        toast(getString(R.string.msg_CopyOK,src.getName())); 
       } 
       }); 
      } 
      } 
     } 
     else 
      Main.this.runOnUiThread(new Runnable() { 
      public void run(){ 
       toast(getString(R.string.msg_CopyNO,src.getName())); 
      } 
      }); 
     FileClip = null; 
     Main.this.runOnUiThread(new Runnable() { 
      public void run(){ 
      getDir(myPath.getText().toString()); 
      } 
     }); 
     } 
    } 
    }); 

    dlg.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
    dlg.setTitle(Moving?getString(R.string.moving):getString(R.string.copying)); 
    dlg.setMessage(src.getName()); 
    dlg.setCancelable(true); 
    dlg.setButton(DialogInterface.BUTTON_NEGATIVE, getString(android.R.string.cancel), new DialogInterface.OnClickListener() 
    { 
    @Override 
    public void onClick(DialogInterface dialog, int which) { 
     dlg.cancel(); 
    } 
    }); 
    dlg.setOnCancelListener(new DialogInterface.OnCancelListener() 
    { 
    @Override 
    public void onCancel(DialogInterface dialog) { 
     copythread.interrupt(); 
     if(dest.exists()) 
     dest.delete(); 
    } 
    }); 
    dlg.setMax((int)src.length()); 
    dlg.show(); 

    copythread.start(); 
} 

這段代碼所做的是試圖複製給定文件(存儲在FileClip字符串)。如你所見,代碼很長,因爲runOnUiThread的過度使用。我想知道如何將所有的

Main.this.runOnUiThread(new Thread(new Runnable() 
    public void run() 
    { 
    //Simple stuff for 6 lines 
    } 
)); 

移動到類或其他東西。我正在考慮的

public class runAtUI implements Runnable 

但我停在那一點,我不知道如何製作構造函數。我希望你知道我的意思,類似於:

new runAtUI() 
{ 
    //This makes less lines IMO, and could be executed 
} 

*注意:我查找有關此的主題,但所有說法都一樣,請使用runOnUiThread。我知道沒關係,但對於短暫的事情(例如顯示吐司(使用相同目的的吐司())或警報(重要),但使用alert() - )則毫無意義。

PS:這是一個簡單的文件管理器,我正在做,因爲缺錢而不會在Google Play上發佈,我也不想使用廣告(打破了「簡單」名稱)。是的,我知道有免費和無廣告(這個詞存在?)和更好的應用程序,但我想學習如何使一個n_n;

任何信息,想法或指導將不勝感激。


編輯#2:謝謝你所有的答案很快!您提供的樣本現在可以工作,但我希望它更靈活。像在JavaScript中的eval("code as string")(沒有代碼是一個字符串)。 我會考慮這個問題的回答,但離開它開放,讓人們給一些更多的想法; d


編輯#3:好吧,首先,比較遺憾的是很久沒有反應。其次,我現在將鏈接添加到當前代碼中,從123行(這一行)到77行代碼pastebin。我還添加了uithread的代碼。 關於該應用程序:如果你想要它的測試,看看它是如何現在或任何東西,給我一個郵件,我會把它發送給你;)

回答

1

你可以創建一個實用工具類來封裝的步驟創建一個由UI線程運行的runnable並調用Toast。這裏有一個簡單的實現:

public abstract class ToastUtils { 
     /** 
     * Displays a toast message, making sure that the toast is always invoked from the main (ui) thread. 
     * @param act Calling Activity 
     * @param text Toast text 
     * @param duration Toast duration 
     */ 
     public static void showToast(final Activity act, final String text, final int duration) { 
     act.runOnUiThread(new Runnable() { 
      public void run() { 
       Toast.makeText(act, text, duration).show(); 
      } 
     }); 
     } 
    } 

使用這個類你可以這樣做敬酒在必要時:

ToastUtils.showToast(這一點,「一些文本」,吐司。LENGTH_SHORT);

+0

謝謝!我會試試看,告訴發生了什麼! – Xch3l 2012-08-11 06:12:01

0

您可以創建活動Handler

Handler handler = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     super.handleMessage(msg); 
     switch (msg.what) { 
     case R.string.cancel: 
      //show toast 
      break; 
     default: 
      break; 
     } 
    } 
}; 

並使用它從你的線程,如:

handler.sendEmptyMessage(R.string.cancel); 
+0

但是,這仍然需要runOnUiThread權利?或者就像創建另一個等待被調用的線程? – Xch3l 2012-08-11 06:04:26

+0

它在你的情況下完成runOnUiThread相同的事情。 – Nick 2012-08-11 06:21:45

+0

你的桅杆表演只在Ui線程中烤麪包。 – 2012-08-11 07:15:05

0

http://developer.android.com/guide/components/processes-and-threads.html

然而,隨着的複雜性操作增長,這種代碼 會變得複雜難以維護ñ。爲了處理更復雜的與工作者線程的交互,您可以考慮在工作線程中使用處理程序 來處理從UI 線程傳遞的消息。但是,最好的解決方案可能是擴展AsyncTask 類,該類簡化了需要 與UI交互的工作線程任務的執行。

...直接跳到...

可以在doInBackground()在隨時打電話publishProgress()來 在UI線程上執行onProgressUpdate()

它看起來對我來說,這是你想要做的。

關於你的其他問題(你應該試着每個主題只問一個問題),用Java複製文件是一個解決的問題。在SO的線程中,我認爲這一個有一些相當不錯的答案:Standard concise way to copy a file in Java?

+0

這或多或少,但由於我正在做簡單的操作,只隱藏進度對話框或顯示消息,沒有考慮到它。 Aaa和另一個(我應該刪除它,對吧?)我想「爲什麼不呢?它會很快」,猜測這是一個常見的新手錯誤 – Xch3l 2012-08-11 07:13:20