在android裏面,咱們常常要上網獲取一些數據,而後更新UI,但獲取數據是要時間的,若是在主線程裏面直接使用獲取數據的代碼的話。整個activity就會卡在那,直至你獲取到數據更新完UI纔會加載完成。在android裏面,若是一個activity卡了5秒,就會被強制回收掉。android
回想一下咱們用過的App,遇到要加載的時候,通常是怎麼樣的呢?確定不會是讓界面卡死在那裏的,最不濟的也有一個"加載中"的圈圈在那轉吧!而後數據加載出來後就消失。網絡
然而android有個很微妙的機制,更新UI只能在UI線程,就是在咱們的主線程,而訪問網絡只能在其餘線程,要怎麼辦呢?答案就是使用Handler類。ide
主要的思路是這個樣子的:佈局
一、讓程序一開始就有一個「加載中」的圈圈(Dialog)。this
二、Handler是在主線程實例化的,屬於主線程。spa
三、在主線程開啓另外一個線程,用來訪問網絡加載數據,加載完後,發消息給Handler類。線程
四、Handler收到消息後,更新UI,再取消那個"加載中"的圈圈。code
假設一種狀況:要訪問網絡,找到一段句子,而後更新咱們的TextViewblog
private Handler handler;//聲明Hanler private TextViwe tv;//聲明TextView protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_first_page); //在主線程中實例化Handler handler = new Handler(){ @Override //收到消息時該作的事情 public void handleMessage(Message msg) { super.handleMessage(msg); //更新TextView UI //取消掉"加載中"的框框 dialog.cancel(); } }; //建立一個窗口來等待加載 dialog = new ProgressDialog(this); dialog.setMessage("數據初始化中..."); dialog.setCancelable(false); dialog.setCanceledOnTouchOutside(false); dialog.show(); //開啓新的線程來訪問網絡,獲取數據 new Thread(new Runnable() { @Override public void run() { //訪問網絡 //給Handler發消息 Message ok = new Message(); handler.sendMessage(ok); } }).start(); }//end onCreate
簡述一下activity運行的順序: 一開始打開App時,activity會把全部的聲明啊,實例化啊,佈局啊什麼的都弄好。然後就進入到dialog.show();這個地方,而後整個界面就是一個圈圈在轉啊轉啊。同時,開啓了一個線程去訪問網絡。即時一個線程在轉啊轉圈圈(Dialog),另外一個線程去訪問了網絡,獲取數據,互不干擾。等到獲取完數據後,會實例化一個Message類,給Handler發信息。Handler接收到信息後,更新UI,而後dialog.cancel();取消掉圈圈。而後咱們看到的就是更新好的界面了。it
以上只是,簡潔化的代碼和口頭的語言,應該還比較易懂。