Android(安卓)Handler鏈哄埗
涓轰粈涔堣鏈塇andler鏈哄埗锛?/h3>
瑙e喅宸ヤ綔绾跨▼鏇存柊UI鐨勯棶棰樸€?br>鐢变簬鍦ˋndroid鏈哄埗涓紝涓轰簡淇濊瘉UI鎿嶄綔鏄嚎绋嬪畨鍏ㄧ殑锛岃瀹氬彧鍏佽涓荤嚎绋嬫洿鏂癆ctivity鐨刄I缁勪欢銆備絾鍦ㄥ疄闄呭紑鍙戜腑瀛樺湪澶氫釜绾跨▼骞跺彂鎿嶄綔UI缁勪欢鐨勬儏鍐碉紝浼氬鑷碪I鎿嶄綔绾跨▼涓嶅畨鍏ㄣ€傛晠閲囩敤Handler鏈哄埗锛屽綋宸ヤ綔绾跨▼闇€瑕佹洿鏂癠I鐨勬椂鍊欙紝閫氳繃Handler閫氱煡涓荤嚎绋嬶紝浠庤€屽湪涓荤嚎绋嬩腑鏇存柊UI銆?/p>
ps1:涓轰粈涔堜笉鐢ㄩ攣鍛紵鐢ㄩ攣浼氫娇UI鐨勮闂€昏緫鍙樺緱澶嶆潅锛岄攣鏈哄埗浼氶檷浣嶶I璁块棶鐨勬晥鐜囷紝閿佷細闃诲鏌愪簺绾跨▼鐨勬墽琛屻€?
Handler鏈哄埗鍖呭惈浜嗕粈涔堬紵
閲嶈姒傚康
- MainThread锛孶I绾跨▼锛屽瓙绾跨▼锛堝伐浣滅嚎绋嬶級
- Handler 澶勭悊鑰?/li>
- Looper 寰幆鍣?/li>
- Message Queue 娑堟伅闃熷垪
- Message 娑堟伅
UI绾跨▼涓庡伐浣滅嚎绋?/h4>
UI绾跨▼灏辨槸APP鍚姩鏃讹紝灏变細寮€鍚竴鏉ctivityThread绾跨▼锛岀О涔嬩负涓荤嚎绋嬨€?/p>
宸ヤ綔绾跨▼锛屽垯鏄湪鎿嶄綔杩囩▼涓紝寮€鍚殑绾跨▼锛屽缃戠粶璇锋眰绾跨▼绛夈€?/p>
Handler
棣栧厛鐪嬩竴涓嬭绫荤殑娉ㄩ噴锛屽氨鍙互鐭ラ亾璇ョ被鐨勫姛鑳藉拰鐢ㄥ浜嗐€?br>Handler浣夸綘鍙互鍙戦€佸拰澶勭悊涓庣嚎绋婱essageQueue鐩稿叧鑱旂殑Message鍜孯unnable銆傛瘡涓疄渚嬮兘涓庝竴涓绾跨▼鐨凪essageQueue鍚戝叧鑱斻€傚綋鍒涘缓Handler鍚庯紝灏变細缁戝畾MessageQueue銆備粠缁戝畾涔嬪悗璧凤紝瀹冨氨鍙互灏哛unnable鍜孧essage浼犲叆娑堟伅闃熷垪涓紝骞跺湪璇诲彇鍒板搴旀秷鎭椂鎵ц浠栦滑銆?/p>
浠庢弿杩颁腑锛屾垜浠彲浠ユ彁鍙栧埌鍑犱釜鍏抽敭淇℃伅銆侶andler涓庣嚎绋嬬粦瀹氾紝涓庣嚎绋嬬殑MessageQueue缁戝畾锛屽ぇ姒傜巼姣忎釜绾跨▼灏卞彧鑳芥湁涓€涓狹essageQueue銆侶andler鍙互鍙戦€佸鐞嗕袱绉嶇被鍨嬬殑鏁版嵁锛孧essage鍜孯unnable銆傦紙杩欎簺鍚庨潰鍏蜂綋鎻忚堪锛?/p>
Looper
Looper鏄负浜嗕负绾跨▼鎻愪緵娑堟伅寰幆銆傞粯璁ゆ儏鍐典笅锛岀嚎绋嬫病鏈塋ooper锛屽彲浠ヤ娇鐢╬repare()鑾峰彇寰幆锛屽苟浣跨敤loop()鏂规硶寮€濮嬪鐞嗕俊鎭紝鍙埌寰幆鍋滄銆?br>涓庝俊鎭惊鐜殑澶ч儴鍒嗕氦浜掔殑閮芥槸閫氳繃Handler绫汇€?/p>
MessageQueue
鍖呭惈Looper瑕佸彂閫佺殑淇℃伅鍒楄〃鐨勪綆绾х被銆傛秷鎭笉鏄洿鎺ユ坊鍔犲埌MessageQueue涓紝鑰屾槸鐢变笌Looper鍏宠仈鐨凥andler绫绘坊鍔犵殑銆?/p>
浠庢弿杩颁腑鍙煡锛孧essageQueue浠庡睘浜嶭ooper銆?/p>
Message
灏辨槸Handler澶勭悊鐨勬秷鎭€傚叾涓湁鍑犱釜姣旇緝閲嶈鐨勫睘鎬э細
- target 鍙戦€佸拰澶勭悊杩欎釜Message鐨凥andler瀵硅薄
- callback 鍦ㄤ富绾跨▼鎵ц鐨勫洖璋?/li>
- when 淇℃伅鐨勪紶閫掓椂闂?/li>
- next 鎸囧悜涓嬩竴鏉essage锛堥摼琛ㄧ粨鏋勶級
鎬庝箞浣跨敤Handler鏈哄埗锛?/h3>
浠庡墠鏂囧彲鐭ワ紝Handler闇€瑕佺粦瀹歁essageQueue锛岃€孧essageQueue浠庡睘浜嶭ooper锛屾墍浠ヤ粠鍒涘缓looper寮€濮嬨€?/p>
娑堟伅澶勭悊
涓€銆佸垱寤篖ooper瀵硅薄
- 涓荤嚎绋?Looper.prepareMainLooper()
涓荤嚎绋嬪垱寤虹殑鏃跺€欎細璋冪敤prepareMainLooper鏂规硶鍒涘缓涓€涓猯ooper鏂规硶锛屾墍浠ュ湪鎴戜滑鑷繁鍐欎唬鐮佹椂锛屾棤闇€鍦ㄤ富绾跨▼鍒涘缓looper銆?/li>
public static void prepareMainLooper() { prepare(false); synchronized (Looper.class) { if (sMainLooper != null) { throw new IllegalStateException("The main Looper has already been prepared."); } sMainLooper = myLooper(); } }
鎴戜滑鍙互鍙戠幇锛岃繖閲屼篃璋冪敤浜唒repare鏂规硶锛屾垜浠湅涓€涓媝repare鐨勬柟娉曘€?/p>
private static void prepare(boolean quitAllowed) { if (sThreadLocal.get() != null) { throw new RuntimeException("Only one Looper may be created per thread"); } sThreadLocal.set(new Looper(quitAllowed)); }
杩欓噷鍑虹幇浜唖ThreadLocal瀛楁锛岃繖涓瓧娈佃static final淇グ锛岃鏄庢槸绫诲叡浜殑甯搁噺銆傦紙鍏充簬ThreadLocal鍏蜂綋璁茶В鍙互鐪嬩笂涓€绡囨枃绔狅級璇ュ父閲忥紝涓烘瘡涓嚎绋嬮兘鎻愪緵绫籐ooper鐨勫壇鏈€?/p>
static final ThreadLocal sThreadLocal = new ThreadLocal();
ps2 : 濡備綍淇濊瘉涓€涓嚎绋嬩腑鍙湁涓€涓狶ooper锛?Looper鐨勬瀯閫犳柟娉曟槸private锛屽彧鑳藉湪prepare涓皟鐢ㄣ€傚苟涓斿鏋滀竴涓猅hreadLocal鑾峰彇鍒扮浉搴旂殑value锛岃鏄庡凡缁忓垱寤鸿繃銆備細鎶涘嚭寮傚父銆?
ps3锛歱repare鐨勬柟娉曚腑鎼哄甫涓€涓竷灏旂被鍨嬪弬鏁帮紝鐢ㄤ簬鍒ゆ柇鏄惁鍙互閫€鍑哄惊鐜€傚瓙绾跨▼鐨勯兘涓簍rue锛屾剰鍛崇潃鍙互閫€鍑猴紱涓荤嚎绋嬬殑涓篺alse锛屾剰鍛崇潃涓嶅彲浠ラ€€鍑恒€?
鎺ョ潃鏉ョ湅鐪嬫瀯閫犲嚱鏁帮紝姣忎釜looper瀵硅薄閮戒細缁戝畾褰撳墠绾跨▼涓庝竴涓秷鎭槦鍒?br>
浜屻€佷娇Looper寮€濮嬪伐浣?/h4>
褰撶劧灏辨槸璋冪敤loop()鏂规硶浜嗐€傜敱浜庤繖娈典唬鐮佸緢闀匡紝鎴戝氨鎴彇涓€浜涳紝鎴戜釜浜鸿涓鸿緝涓哄叧閿殑浠g爜鍚с€?/p>
public static void loop() { final Looper me = myLooper(); if (me == null) { throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread."); } final MessageQueue queue = me.mQueue; ...... for (;;) { Message msg = queue.next(); // might block if (msg == null) { // No message indicates that the message queue is quitting. return; } ...... try { msg.target.dispatchMessage(msg); if (observer != null) { observer.messageDispatched(token, msg); } dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0; } catch (Exception exception) { if (observer != null) { observer.dispatchingThrewException(token, msg, exception); } throw exception; } finally { ThreadLocalWorkSource.restore(origWorkSource); if (traceTag != 0) { Trace.traceEnd(traceTag); } } ...... } }
- 棣栧厛鑾峰緱褰撳墠鐨凩ooper鐨勬秷鎭槦鍒?MessageQueue queue = me.mQueue锛?/li>
- 鐒跺悗寮€鍚寰幆 for锛堬細锛氾級
- 閫氳繃娑堟伅闃熷垪鑾峰彇MessageQueue鑾峰彇淇℃伅 Message msg = queue.next();锛堝彲鑳介€犳垚闃诲锛?/li>
- 鐒跺悗澶勭悊娑堟伅 msg.target.dispatchMessage(msg) 鍓嶆枃宸茬煡Message鐨則arget鐨勫氨鏄彂閫佸拰澶勭悊璇ュ璞$殑Handler銆?/li>
ps4: 濡備綍閫€鍑哄惊鐜€俵ooper璋冪敤quit鏂规硶锛屾垨鑰卶uitSafely鏂规硶鍚庯紝闃熷垪灏变細鏀惧洖msg == null锛岃繖鏍峰氨鍙互缁撴潫寰幆銆傞【鍚嶆€濅箟锛宷uit灏辨槸绔嬪嵆閫€鍑猴紝鑰宷uitSafely鍒欐墦涓婃爣蹇楋紝褰撴秷鎭鐞嗗畬鍏ㄤ箣鍚庢墠缁撴潫寰幆銆?
ps5:涓轰粈涔堣繖閲岄樆濉炰簡锛熶細涓嶄細褰卞搷涓荤嚎绋嬶紝鎴栬€呭奖鍝岰PU鍛紵杩欎篃鏄竴涓€煎緱鍏虫敞鐨勯棶棰橈紝瀹瑰悗闈㈠垎鏋愩€?
涓夈€丮essageQueue璇诲彇鏁版嵁
浠嶇劧杩樻槸璐村嚭鍏抽敭浠g爜
Message next() { ...... int nextPollTimeoutMillis = 0; for (;;) { if (nextPollTimeoutMillis != 0) { Binder.flushPendingCommands(); } nativePollOnce(ptr, nextPollTimeoutMillis); synchronized (this) { // Try to retrieve the next message. Return if found. // 鑾峰彇褰撳墠鏃堕棿 浠ヤ究寮傛娑堟伅 final long now = SystemClock.uptimeMillis(); Message prevMsg = null; Message msg = mMessages; // 娑堟伅灞忛殰锛屾煡鎵炬槸鍚︽湁寮傛娑堟伅鍦ㄩ槦鍒椾腑 if (msg != null && msg.target == null) { // Stalled by a barrier. Find the next asynchronous message in the queue. do { prevMsg = msg; msg = msg.next; } while (msg != null && !msg.isAsynchronous()); } if (msg != null) { // 澶勭悊寤惰繜娑堟伅 if (now < msg.when) { // Next message is not ready. Set a timeout to wake up when it is ready. nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE); } else { // Got a message. mBlocked = false; if (prevMsg != null) { prevMsg.next = msg.next; } else { mMessages = msg.next; } msg.next = null; if (DEBUG) Log.v(TAG, "Returning message: " + msg); msg.markInUse(); return msg; } } else { // No more messages. nextPollTimeoutMillis = -1; } ...... } ...... } }
涓嶉毦鍙戠幇nextPollTimeoutMillis鏄緢閲嶈鐨勫弬鏁般€傛甯稿惊鐜椂锛屾鍙傛暟涓?銆傚綋鏈夊欢杩熸秷鎭紝娑堟伅娌″噯澶囧ソ鏃讹紝鍒欎細璁剧疆涓€涓欢杩熸椂闂达紝璁╀笅涓€娆″惊鐜墽琛屻€傚綋message涓虹┖鏃讹紝姝ゅ弬鏁颁細璁剧疆鎴?1銆?/p>
nativePollOnce鏂规硶鏄竴涓湰鍦版柟娉曪紝涔熸槸闃诲杩欎釜娑堟伅闃熷垪鐨勬柟娉曘€傚綋鍓嶉潰鍙傛暟涓?1鏃讹紝灏变細浣挎秷鎭槦鍒楅櫡鍏ョ瓑寰呯姸鎬併€?/p>
娉ㄦ剰杩欓噷鏈変釜鍚屾鏂规硶锛岄攣浣忕被MessageQueue瀵硅薄銆傜敱浜庡鐞嗙殑娑堟伅锛屾槸鐢卞叾浠栫嚎绋嬩紶鍏ョ殑锛屼负浜嗕繚璇佺嚎绋嬪畨鍏紝灏卞緱Synchronized銆?/p>
鍥涖€丠andler.dispatchMessage(msg)
浠庡墠鏂囧緱鐭anler搴旇鍙互澶勭悊涓ょ被鏁版嵁锛熶负浠€涔堣繖閲屽氨鍙湁Message鍛紵鍚庢枃鍐嶈锛屾垜浠厛鐪嬪鐞嗘柟娉曪細
褰搈essage鏈夊洖璋冩椂锛堝疄闄呬笂灏辨槸鍓嶆枃鐨凴unnable鐨勭被鍨嬫暟鎹級锛屽氨浼氳皟鐢ㄨ繖涓洖璋冪殑run鏂规硶銆?/p>
message.callback.run();
褰搈sg.callback涓虹┖鏃讹紝鍒欐澶勪細浣跨敤鑷畾鐨刪anlerMessage鏂规硶銆?/p>
浠ヤ笂鍥涙灏辨槸Handler鏈哄埗澶勭悊娑堟伅鐨勬楠や簡銆傞偅涔圚andler鏈哄埗鏄浣曚笂浼燤essage鐨勫憿锛?/p>
涓婁紶娑堟伅
涓€銆侀噸鍐橦andler
浠庡墠鏂囦笁绉嶅鐞嗘柟娉曚腑锛屾垜浠氨鍙互澶嶅啓鍑轰笁绉嶉噸鍐橦andler鏂规硶銆?/p>
- 鏂板缓Handler瀛愮被锛屽疄鐜癶andlerMessage澶勭悊鏂规硶銆傦紙瀵瑰簲鏈€鍚庝竴绉嶅鐞嗭級
- 鍖垮悕鍐呴儴绫伙紝閫氳繃Callback瀹炵幇handlerMessag銆傦紙瀵瑰簲鍊掓暟绗簩绉嶅鐞嗭級
- 鍦╬ost鏂规硶涓紶鍏unnable锛堝搴旂涓夌澶勭悊锛?/li>
ps6: Handler瑕佸湪澶勭悊璇andler锛堜竴鑸负涓荤嚎绋嬶級鐨勭嚎绋嬩腑鍒涘缓锛岀劧鍚庡湪宸ヤ綔璋冪敤銆?
ps7锛氳繖閲岀殑Runnable鎺ュ彛锛屽彧鏄綔涓轰竴绉嶅0鏄庯紝鑰屼笉鏄儚浼犵粺鐨勮寮€鍚竴涓柊鐨勭嚎绋嬶紝鍒囪銆?
ps8锛氬瓙绾跨▼涓彲浠ョ敤MainLooper鍘诲垱寤篐andler鍚楋紵 瀛愮嚎绋嬩腑Handler handler = new Handler(Looper.getMainLooper());锛屾鏃朵袱鑰呭氨涓嶅湪涓€涓嚎绋嬩腑銆?
浜屻€佸垱寤烘秷鎭璞?/h4> - 鍒涘缓Runnable瀵硅薄锛屽彲浠ョ洿鎺ュ疄鐜颁竴涓被锛屼篃鍙互鐩存帴鍦╬ost鏂规硶鍐呬娇鐢ㄥ尶鍚嶅唴閮ㄧ被銆?/li>
-
鍒涘缓Message瀵硅薄
- 鍒涘缓涓句緥
Message msg = Message.obtain(); // 瀹炰緥鍖栨秷鎭璞? msg.what = 1; // 娑堟伅鏍囪瘑 msg.obj = "AA"; // 娑堟伅鍐呭瀛樻斁
*
ps9: 鍒涘缓鐢ㄤ簡涓嶅父瑙佺殑obtain锛岃€屼笉鏄痭ew锛屾槸鍥犱负Message鑷甫缂撳啿姹狅紝閬垮厤姣忔閮戒娇鐢╪ew閲嶆柊鍒嗛厤鍐呭瓨锛屽彧鏈夊綋绾跨▼姹犳棤瀵硅薄鏃讹紝鎵嶄細new鏂板璞°€?
涓夈€佸彂閫佷俊鎭埌闃熷垪
鍒涘缓Message瀵硅薄
- 鍒涘缓涓句緥
Message msg = Message.obtain(); // 瀹炰緥鍖栨秷鎭璞? msg.what = 1; // 娑堟伅鏍囪瘑 msg.obj = "AA"; // 娑堟伅鍐呭瀛樻斁
*
瀵瑰簲涓ょ绫诲瀷鏁版嵁锛屼害鏈変袱鏉¤矾寰勶細
-
post锛圧unnable r锛?/p>
- sendMessageDelayed(getPostMessage(r), 0)锛?getPostMessage鏂规硶涓紝灏哛unnable鎺ュ彛灏佽鎴愪簡message瀵硅薄锛屽苟灏唕璁剧疆鎴愮被msg.callback銆?/li>
- sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- enqueueMessage(queue, msg, uptimeMillis)锛?灏唌sg涓庡綋鍓嶇殑Handler缁戝畾锛屽苟灏嗗叾鎻掑叆闃熷垪涓?/li>
- queue.enqueueMessage(msg, uptimeMillis)锛涜繖姝ヨ緝涓哄叧閿紝璐翠竴涓嬫簮鐮併€傝繖閲屼娇鐢ㄧ殑鏄崟閾捐〃鐨勫娣绘柟娉曪紝閾捐〃鐨勫ソ澶勬槸澧炲垹渚挎嵎锛屼絾鏄煡璇笉渚垮埄锛岃繖杈逛篃寰堝皯鏌ヨ鐨勬柟娉曪紝鏁呬娇鐢ㄩ摼琛ㄤ篃杈冧负鍚堥€傘€?/li>
boolean enqueueMessage(Message msg, long when) { ...... synchronized (this) { ...... msg.markInUse(); msg.when = when; Message p = mMessages; boolean needWake; // 褰撳綋鍓嶉槦鍒椾负绌烘椂锛屽敜閱掔瓑寰呯殑闃熷垪锛屽苟鎻掑叆澶寸粨鐐? if (p == null || when == 0 || when < p.when) { // New head, wake up the event queue if blocked. msg.next = p; mMessages = msg; needWake = mBlocked; } else { // Inserted within the middle of the queue. Usually we don't have to wake // up the event queue unless there is a barrier at the head of the queue // and the message is the earliest asynchronous message in the queue. needWake = mBlocked && p.target == null && msg.isAsynchronous(); Message prev; // 褰撳綋鍓嶉槦鍒椾笉涓虹┖锛屽垯鏍规嵁鏃堕棿鎻掑叆锛屽埌閫傚綋鐨勪綅缃? for (;;) { prev = p; p = p.next; if (p == null || when < p.when) { break; } if (needWake && p.isAsynchronous()) { needWake = false; } } msg.next = p; // invariant: p == prev.next prev.next = msg; } // We can assume mPtr != 0 because mQuitting is false. if (needWake) { nativeWake(mPtr); } } return true; }
-
sendMessage锛圧unnable r锛?/p>
- endMessageDelayed(msg, 0);
- sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
- enqueueMessage(queue, msg, uptimeMillis)锛?/li>
- queue.enqueueMessage(msg, uptimeMillis);
姝ラ鍩烘湰鍚屼笂銆?/p>
ps10:濡傛灉闇€瑕佽皟鐢ㄥ欢杩熺殑璇濓紝璋冪敤postDelayed鏂规硶锛屾渶鍚庡簳灞傝繕鏄拰涓婇潰鐩镐技銆?
ps11锛氬鏋滅畝鍗曟洿鏂癠I鍒欑洿鎺ヤ娇鐢≧unnable鍗冲彲锛堝彲鑳藉鑷寸嚎绋嬭€﹀悎搴﹂珮锛夈€傝嫢鏄浼犻€掓暟鎹紝鍒欎娇鐢∕essage銆?
鑷存锛屾€庝箞浣跨敤Handler鏈哄埗宸茬粡璁茶堪瀹屾垚浜嗐€備絾鏄疕andler鏈哄埗鐨勪娇鐢ㄨ繕鏄瓨鍦ㄤ竴浜涢棶棰樼殑锛岃鎴戜滑缁х画鎺㈢┒銆?/p>
Handler浣跨敤鐤戦棶
涓€銆佸鐞嗗欢杩熸秷鎭細
1銆丮essageQueue.next()鍦ㄥ彇鍑篗sg鏃讹紝濡傛灉鍙戠幇娑堟伅A鏈夊欢杩熶笖鏃堕棿娌″埌锛屼細闃诲娑堟伅闃熷垪銆?br>2銆佸鏋滄鏃舵湁闈炲欢杩熺殑鏂版秷鎭疊锛屼細灏嗗叾鍔犲叆娑堟伅闃熷垪, 涓斿浜庢秷鎭疉鐨勫墠闈紝骞朵笖鍞ら啋闃诲鐨勬秷鎭槦鍒椼€?br>3銆佸敜閱掑悗浼氭嬁鍑洪槦鍒楀ご閮ㄧ殑娑堟伅B锛岃繘琛屽鐞嗐€傜劧鍚庝細缁х画鍥犱负娑堟伅A鑰岄樆濉炪€?br>4銆佸鏋滆揪鍒颁簡娑堟伅A寤惰繜鐨勬椂闂达紝浼氬彇鍑烘秷鎭疉杩涜澶勭悊銆?/p>
浜屻€丩ooper 姝诲惊鐜负浠€涔堜笉浼氬鑷村簲鐢ㄥ崱姝伙紵浼氭秷鑰楄秺鏉ヨ秺澶氱殑璧勬簮鍢涳紵
ActivityThread瀹炶川鏄彧鏄疉pp鐨勫叆鍙g被锛岃€屼笉鏄湡姝g殑绾跨▼銆?/p>
瀵逛簬绾跨▼鍗虫槸涓€娈靛彲鎵ц鐨勪唬鐮侊紝褰撳彲鎵ц浠g爜鎵ц瀹屾垚鍚庯紝绾跨▼鐢熷懡鍛ㄦ湡渚胯缁堟浜嗭紝绾跨▼閫€鍑恒€傝€屽浜庝富绾跨▼锛屾垜浠槸缁濅笉甯屾湜浼氳杩愯涓€娈垫椂闂达紝鑷繁灏遍€€鍑猴紝閭d箞濡備綍淇濊瘉鑳戒竴鐩村瓨娲诲憿锛熺畝鍗曞仛娉曞氨鏄彲鎵ц浠g爜鏄兘涓€鐩存墽琛屼笅鍘荤殑锛屾寰幆渚胯兘淇濊瘉涓嶄細琚€€鍑恒€?/p>
鑷充簬娑堣€楄祫婧愶紝娑夊強鍒癳poll鏈哄埗锛堝埌IO鐨勬椂鍊欏湪缁х画璁茶В鍚э級锛岃鏈哄埗浼氬啀鏈夋暟鎹埌杈炬椂锛屾墠鍞ら啋涓荤嚎绋嬪伐浣溿€傚惁鍒欏氨璁╀富绾跨▼浼戠湢銆?/p>
涓夈€佷富绾跨▼鐨勬秷鎭惊鐜満鍒舵槸浠€涔堬紵
姝ょ偣涓嶅娓呮櫚锛屼互鍚庤缁嗙爺绌躲€?/p>
鍥涖€丠andler鐨勫唴瀛樻硠婕忛棶棰樸€?/h4> - 褰揌andler鏄潪闈欐€佸唴閮ㄧ被鎴栧尶鍚岺andler鍐呴儴绫绘椂锛屼細鎸佹湁澶栭儴搴旂敤锛岃繖鏍蜂細瀵艰嚧涓€涓棶棰樸€傚綋瑕侀攢姣佸綋鍓岮ctivity鏃讹紝鍙兘鏈夋秷鎭湭澶勭悊瀹屽叏锛孧essage鎸囧悜浜咹andler锛岃€屽綋鍓岺andler鍙堟寔鏈堿ctivity锛屾墍浠ュ綋鍓嶇殑Activity涓嶈兘琚洖鏀讹紝鍙兘閫犳垚鍐呭瓨娉勬紡銆?/li>
-
瑙e喅鍔炴硶锛?/p>
- 1銆佸瓨鍦ㄢ€滄湭琚鐞?/ 姝e鐞嗙殑娑堟伅 -> Handler瀹炰緥 -> 澶栭儴绫烩€?鐨勫紩鐢ㄥ叧绯?br>棣栧厛灏咹andler璁剧疆涓洪潤鎬佸唴閮ㄧ被锛岀劧鍚庢寔鏈堿ctivity鐨勫急寮曠敤瀹炰緥銆備繚璇佹秷鎭槦鍒椾腑鎵€鏈夋秷鎭兘鑳芥墽琛屻€?/li>
- 2銆丠andler鐨勭敓鍛藉懆鏈?> 澶栭儴绫荤殑鐢熷懡鍛ㄦ湡
鍦∣nDestory鏂规硶涓紝娓呯┖Handle闃熷垪锛屽苟鐩存帴缁堟handler,mHandler.removeCallbacksAndMessages(null);
浜斻€佽ˉ鍏?/h4>
瑙e喅鍔炴硶锛?/p>
- 1銆佸瓨鍦ㄢ€滄湭琚鐞?/ 姝e鐞嗙殑娑堟伅 -> Handler瀹炰緥 -> 澶栭儴绫烩€?鐨勫紩鐢ㄥ叧绯?br>棣栧厛灏咹andler璁剧疆涓洪潤鎬佸唴閮ㄧ被锛岀劧鍚庢寔鏈堿ctivity鐨勫急寮曠敤瀹炰緥銆備繚璇佹秷鎭槦鍒椾腑鎵€鏈夋秷鎭兘鑳芥墽琛屻€?/li>
- 2銆丠andler鐨勭敓鍛藉懆鏈?> 澶栭儴绫荤殑鐢熷懡鍛ㄦ湡
鍦∣nDestory鏂规硶涓紝娓呯┖Handle闃熷垪锛屽苟鐩存帴缁堟handler,mHandler.removeCallbacksAndMessages(null);
闃熷垪涓殑鍐呭锛堟棤璁篗essage杩樻槸Runnable锛夊彲浠ヨ姹傞┈涓婃墽琛岋紝寤惰繜涓€瀹氭椂闂存墽琛屾垨鑰呮寚瀹氭煇涓椂鍒绘墽琛岋紝濡傛灉灏嗕粬浠斁缃湪闃熷垪澶达紝鍒欒〃绀哄叿鏈夋渶楂樻湁闄愮骇鍒紝绔嬪嵆鎵ц銆傝繖浜涘嚱鏁板寘鎷湁:sendMessage(), sendMessageAtFrontOfQueue(), sendMessageAtTime(), sendMessageDelayed()浠ュ強鐢ㄤ簬鍦ㄩ槦鍒椾腑鍔犲叆Runnable鐨刾ost(), postAtFrontOfQueue(), postAtTime(),postDelay()銆?/p>
更多相关文章
- 代码中设置drawableleft
- android 3.0 隐藏 系统标题栏
- Android开发中activity切换动画的实现
- Android(安卓)学习 笔记_05. 文件下载
- Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
- 技术博客汇总
- android 2.3 wifi (一)
- AndRoid Notification的清空和修改
- Android中的Chronometer