2013-09-25 57 views
3

在我的mainActivity中,這是我的應用程序的唯一活動,我創建了下面的處理程序並在其中運行一個可運行的程序。我可以在處理程序/可運行內部執行網絡操作(UI阻塞)嗎?

我對處理程序和它們運行的​​地方有一些誤解。

看到代碼

Handler handler; 

    @Override 
    protected void onCreate(Bundle bundle) 
    { 
     handler = new Handler(); 
     handler.postDelayed(r , 5000); 
    } 

    Runnable r = new Runnable() 
    { 
     @Override 
     public void run() { 
       FetchServerAndUpdateStatus(); //network stuff in here 
       handler.postDelayed(r , 5000); 
     } 
    } 
  • 我認爲這個代碼仍然會在UI線程中運行,我就不能在那裏做任何網絡電話沒有?
  • 如果是,我該怎麼辦?創建並使用單獨的線程?
  • 如果我創建了一個新的線程,我怎樣才能運行postdelayed方法?線程沒有延遲?
  • 不使用處理程序/可運行和使用TimerTask的和Runnable接口,而不是一個更好的方法?或者,就像上面的處理程序/ runnable一樣,它也將在UI線程上運行,除非在單獨的內部創建。
+0

我覺得我失去了一些東西。 Handler真的具有可運行的構造函數嗎? – joozek

+0

@ joozek不,他們不。 postdelayed需要壽,我的壞。 – tony9099

回答

2

當你構建它必然是建立在線程處理程序。

onCreate()在UI線程上運行,所以這個處理程序將被綁定到主線程上的Looper,從而在該線程上運行。

如果你想要一個處理程序,你可以使用另一個線程,你可以構造一個。 見彎針文檔:https://developer.android.com/reference/android/os/Looper.html

其中有塊:

class LooperThread extends Thread { 
    public Handler mHandler; 

    public void run() { 
     Looper.prepare(); 

     mHandler = new Handler() { 
      public void handleMessage(Message msg) { 
       // process incoming messages here 
      } 
     }; 

     Looper.loop(); 
    } 
} 

加入這個類,然後在你的onCreate做到以下幾點:

mLooperThread = new LooperThread(); 
mLooperThread.start(); 
mLooperThread.mHandler.postDelayed(r , 5000); 

這將導致可運行來運行不在UI線程上,這可能是你想要的。

對於需要與UI進行交互的任務,AsyncTask可能會更好,因爲它包含一個機制來運行在UI線程上完成任務時觸摸視圖的東西,因爲任何接觸View的東西都必須在UI線程。

爲UI線程上執行的其他機制是張貼到視圖本身:

https://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable) 或 [https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable,長)](https://developer.android.com/reference/android/view/View.html#postDelayed(java.lang.Runnable,長))

,或者要求活動對UI運行它爲您提供:

https://developer.android.com/reference/android/app/Activity.html#runOnUiThread(java.lang.Runnable)

+0

非常感謝。我想迄今爲止,你給出的解釋是最精確和新手友好的。我認爲很多人認爲當在onCreate()或onResume()中創建一個處理程序時,他們會在一個單獨的線程上啓動它,實際上它們不是。處理程序和線程之間有很大的混淆,導致我迷失方向。感謝您填寫空白處。 – tony9099

0
  1. 這取決於你和你的處理器做什麼,你沒有表現出,你想怎麼獲得m_handler。如果您使用new Handler(Looper.getMainLooper())創建它,它將在UI線程上運行。
  2. 如果你想在後臺運行(網絡操作)的代碼,你應該使用AsyncTask
+0

你能詳細解釋一下Activty.getHandler()的東西,我可以從哪裏獲得它而不是活動?是的,我肯定會使用網絡資料,所以我需要它在後臺運行。上面的代碼就是這樣,是否在UI線程或其他線程上運行? – tony9099

+0

對不起,我搞砸了一下。你可以通過調用'Looper.getMainLooper()'獲得主_looper_。 Looper是循環運行代碼的東西,你可以用'new Handler(looper)'附加一個處理程序。無論如何,我會編輯我的答案 – joozek

+0

如果我創建它沒有任何東西,像上面那樣,它運行在哪裏? – tony9099

相關問題