涓轰粈涔堣鏈塇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鏂板璞°€?

涓夈€佸彂閫佷俊鎭埌闃熷垪

瀵瑰簲涓ょ绫诲瀷鏁版嵁锛屼害鏈変袱鏉¤矾寰勶細

  • 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>

闃熷垪涓殑鍐呭锛堟棤璁篗essage杩樻槸Runnable锛夊彲浠ヨ姹傞┈涓婃墽琛岋紝寤惰繜涓€瀹氭椂闂存墽琛屾垨鑰呮寚瀹氭煇涓椂鍒绘墽琛岋紝濡傛灉灏嗕粬浠斁缃湪闃熷垪澶达紝鍒欒〃绀哄叿鏈夋渶楂樻湁闄愮骇鍒紝绔嬪嵆鎵ц銆傝繖浜涘嚱鏁板寘鎷湁:sendMessage(), sendMessageAtFrontOfQueue(), sendMessageAtTime(), sendMessageDelayed()浠ュ強鐢ㄤ簬鍦ㄩ槦鍒椾腑鍔犲叆Runnable鐨刾ost(), postAtFrontOfQueue(), postAtTime(),postDelay()銆?/p>

更多相关文章

  1. 代码中设置drawableleft
  2. android 3.0 隐藏 系统标题栏
  3. Android开发中activity切换动画的实现
  4. Android(安卓)学习 笔记_05. 文件下载
  5. Android中直播视频技术探究之—摄像头Camera视频源数据采集解析
  6. 技术博客汇总
  7. android 2.3 wifi (一)
  8. AndRoid Notification的清空和修改
  9. Android中的Chronometer

随机推荐

  1. 解决listView挡住button的问题
  2. Android 的一个错误的解决
  3. Android(安卓)BaseAdapter与ListView的使
  4. 【从头学android】第二个程序同一个Activ
  5. Android -- Wifi的save()操作
  6. android Vibrator震动效果
  7. Android UI列表的上拉下拉刷新之Android-
  8. Android利用Timer实现倒计时效果小demo
  9. Android开启adb root 和 Console Root
  10. Android InputStream转Bitmap