-
handler-4查看全部
-
handler-3查看全部
-
handler_2查看全部
-
handler_1查看全部
-
handler_1查看全部
-
handler是用來(lái)發(fā)送和處理消息的,更新UI的查看全部
-
handler 消息處理機(jī)制 更新UI界面查看全部
-
1.不能直接在非UI線程直接更新UI(大多數(shù)時(shí)候)。<br> 2.每次創(chuàng)建Handler時(shí)需要給它綁定一個(gè)looper,如果是主線程不給定具體的looper則會(huì)綁定默認(rèn)的looper。<br> 3.子線程運(yùn)行時(shí)一定要調(diào)用start()方法。<br> 4.在某些特殊情況下在非UI線程是可以更新UI的//不推薦使用(當(dāng)剛啟動(dòng)Activity即onCreate里面此時(shí)onResume方法還沒(méi)有執(zhí)行的時(shí)候可以,因?yàn)樵诰€程中更新UI時(shí)會(huì)調(diào)用ViewParent.invalidateChild()方法檢查當(dāng)前的Thread是否是UIThread,若為UIThread則可以更新(ViewParent是一個(gè)接口類,其實(shí)現(xiàn)是ViewRootImpl;invalidateChild()方法調(diào)用checkThread()方法來(lái)檢查線程是否為主線程)。ViewRootImp是在onResume方法中初始化的,所以只要在ViewRootImpl創(chuàng)建之前更新UI(在onCreate方法中創(chuàng)建線程并執(zhí)行,此時(shí)還沒(méi)有初始化ViewRootImp),就可以逃避掉checkThread()的檢查進(jìn)而更新UI。)查看全部
-
所有更新UI的操作,都要使用view的invalidate方法 settext方法中也使用了invalidate方法 invalidate(true) 判斷UI線程 invalidateChild(this,null)中調(diào)用invalidateChildInParent方法 中使用checkThread,檢查當(dāng)前更新UI的操作是否在主線程之中 在Onresume方法中創(chuàng)建viewrootmp oncreate方法在onresume方法之前,所以在oncreate方法中沒(méi)有檢測(cè)子線程是否與UI線程相等查看全部
-
Android中更新UI的幾種方式: 1. activity.runOnUiThread() 2. handler.post() 3. handler.sendMessage() 4. view.post()查看全部
-
1.創(chuàng)建主線程的handler,并向子線程發(fā)送消息: //主線程的handler Handler handler = new Handler(){ public void handleMessage(android.os.Message msg) { Message message = new Message(); threadHandler.sendMessageDelayed(message, 1000);//向子線程發(fā)送消息 }; }; 2.創(chuàng)建子線程的handler,向主線程發(fā)送消息,要關(guān)聯(lián)一個(gè)threadHandler,threadHandler.getLooper()得到一個(gè)looper對(duì)象 HandlerThread handlerThread = new HandlerThread("handler thread"); handlerThread.start();//不要忘記調(diào)用start方法! //子線程的handler threadHandler = new Handler(handlerThread.getLooper()){ @Override public void handleMessage(Message msg) {//處理消息 Message message = new Message(); handler.sendMessageDelayed(message, 1000); } };查看全部
-
handlerThread 注意的地方 創(chuàng)建handler對(duì)象 指定Looper 在MyThread 的Looper對(duì)象 空指針異常 多線程并發(fā) 兩個(gè)線程可能Looper沒(méi)有創(chuàng)建 HandlerThread可以避免空指針問(wèn)題 handlerThread對(duì)象 handler對(duì)象 thread.getLooper 原理判斷線程是否或者 空則等待 run方法創(chuàng)建 Looper通知加線程同步的判斷 默認(rèn)所有的handlerThread中下載網(wǎng)絡(luò)資源 把所有的任務(wù)的發(fā)送處理 調(diào)用handlerThread查看全部
-
自定義Thread MyThread extend Thead 調(diào)用 Looper.prepare 與子線程相關(guān)的handler handler和子線程關(guān)聯(lián) thread.sendMessage 如果在主線程中創(chuàng)建一個(gè)handler,并重寫(xiě)handlemessage方法,那么一定不要在這里執(zhí)行耗時(shí)操作,這樣有可能會(huì)將主線程卡死 創(chuàng)建一個(gè)與線程相關(guān)的Handler: 1. 在線程中通過(guò)Looper.prepare()方法創(chuàng)建一個(gè)與線程相關(guān)的Looper對(duì)象; 2. 在線程中通過(guò)Handler的new關(guān)鍵字,創(chuàng)建一個(gè)Handler對(duì)象,這個(gè)對(duì)象在創(chuàng)建的時(shí)候會(huì)關(guān)聯(lián)上1中創(chuàng)建的Looper對(duì)象 3. 調(diào)用Looper對(duì)象的loop()方法去輪詢它的MessageQueue 4. 通過(guò)其他的線程拿到這個(gè)線程的Handler對(duì)象之后調(diào)用sendMessage()之后,在這個(gè)線程中就可以進(jìn)行Message的處理了。<br> <br> 我們一般是在主線程中創(chuàng)建Handler對(duì)象,在主線程中處理Message,在子線程中調(diào)用這個(gè)Handler對(duì)象的sendMessage()來(lái)發(fā)送message。所以Handler是在哪個(gè)線程創(chuàng)建就有哪個(gè)線程處理Message和輪詢,而由別的線程負(fù)責(zé)給這個(gè)Handler發(fā)送Message。 * 每個(gè)線程都對(duì)應(yīng)一個(gè)looper,在線程里面創(chuàng)建的handler默認(rèn)都會(huì)與這個(gè)looper對(duì)應(yīng) * 一個(gè)線程可以有多個(gè)handler與唯一的一個(gè)looper對(duì)應(yīng),有且只有一個(gè)looper * 這里主要是讓我們熟悉在oncreat創(chuàng)建的handler與子線程創(chuàng)建handler * oncreate創(chuàng)建的handler他默認(rèn)里面會(huì)有一個(gè)looper與之對(duì)應(yīng) * 所以我們自己在子線程中創(chuàng)建handler對(duì)象的時(shí)候我們應(yīng)該要自主創(chuàng)建一個(gè)looper查看全部
-
使用“Message”方式“發(fā)送消息”,使“Handler處理消息,并更新UI” 1.定義Handler,并且實(shí)例化,使用默認(rèn)構(gòu)造函數(shù)即可。 2.重寫(xiě)handlerMessage方法。 private Handler msgHandler=new Handler(){ //定義handler,重寫(xiě)處理message方法。當(dāng)該handler發(fā)送消息的時(shí)候,這個(gè)方法會(huì)被執(zhí)行。 public void handleMessage(android.os.Message msg) { //msg為當(dāng)有sendMessage方法調(diào)用時(shí),傳過(guò)來(lái)的Message對(duì)象。 mTextView.setText("msg:"+msg.arg1); }; }; 3.定義Message對(duì)象。其中,Message提供了三個(gè)公共變量。arg1,arg2,obj,可以將消息放入其中,作為消息信息。然后發(fā)送消息即可 new Thread() { public void run() { Message message=msgHandler.obtainMessage();//從Handler對(duì)象中獲取Message對(duì)象,而不是自己new,這樣效率高。 message.arg1=1; message.sendToTarget(); //對(duì)于從handler對(duì)象中獲取的message,可以直接使用該方法發(fā)送消息。 //msgHandler.sendMessage(message); //發(fā)送消息 }; }.start(); 知識(shí)拓展: 1。實(shí)例化Handler時(shí),可以使用帶一個(gè)Callback接口參數(shù)的構(gòu)造函數(shù)。 其中Callback有一個(gè)未實(shí)現(xiàn)的方法。 這個(gè)方法有一個(gè)返回值(boolean) 2.當(dāng)該Handler收到消息時(shí),首先會(huì)調(diào)用Callback中的消息處理方法。 2.1 如果返回值為false,消息不會(huì)被截?cái)?。Handler依然可以處理該消息。 2.2 如果返回值為true,消息將會(huì)被截?cái)?。Handler中的處理消息方法不會(huì)被執(zhí)行。查看全部
-
使用“Handler”更新UI 1.使用post或postDelayed()方法。 2.在子線程中可以調(diào)用post方法。來(lái)將更新UI消息加入到隊(duì)列中。這樣就可以更新UI了 其中。需要一個(gè)參數(shù)。Runnable,在run方法下寫(xiě)更新UI的操作即可。 new Thread(new Runnable() { @Override public void run() { /** * 將Runnable中要執(zhí)行的內(nèi)容加入消息隊(duì)列。 * 可以在這之中更新ui * */ mHandler.post(new Runnable() { @Override public void run() { mTextView.setText("我是被更新后的值"); } }); } }).start(); 3.使用mHandler.postDelayed(myRunnable, 1000);更新UI同樣道理,但是會(huì)在延遲時(shí)間之后執(zhí)行??梢允褂闷鋪?lái)進(jìn)行輪換操作查看全部
舉報(bào)
0/150
提交
取消