中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

AndroidLooper用法及分析-創(chuàng)新互聯(lián)

先看一下源碼中對looper進行的解釋,
在這里插入圖片描述
根據(jù)注釋內(nèi)容,可以了解到,消息循環(huán)的交互情況都是通過handler進行的。
再不和handler搭配的情況下,通常都是以looper.prepare和looper.loop這種方式成對出現(xiàn)的,使在這兩句話中間執(zhí)行的內(nèi)容都是通過looper進行通信執(zhí)行相應內(nèi)容。

成都創(chuàng)新互聯(lián)長期為1000+客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為孝昌企業(yè)提供專業(yè)的做網(wǎng)站、網(wǎng)站建設孝昌網(wǎng)站改版等技術服務。擁有十余年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。

此類還有對api實施進行注釋描述,貼上來也一起看一下吧。
在這里插入圖片描述
這部分描述可以看到,looper基于MessageQueue并可以影響任務隊列的狀態(tài)。通常都是在MessageQueue或者Handler上進行定義,這里講了looper的作用和其定義的時機。

個人理解:
looper通常都是在非主線程的時候使用讓部分代碼塊可以作用在主線程,進行ui更新等一些操作。用到的地方有很多,在activityThread當中可以看到很多l(xiāng)ooper的影子。在什么時候用源碼的注釋上面解釋的挺清晰了。
該類中中在跨進程部分運用的都是binder進行通信,threadlocal進行線程管理。

此類中不對外暴露的方法不進行介紹。
----------------------------------------------------------我是分割線----------------------------------------------------------

方法介紹

prepare()方法最終會傳遞true到 prepare(boolean quitAllowed)方法當中,這里直接看 prepare(boolean quitAllowed)方法。
在這里插入圖片描述
這里可以看到該方法會優(yōu)先判斷threadlocal線程池里面是否為null,里面有數(shù)據(jù)的時候就會拋出運行異常(因為代表這個時候looper有正在運行,必須要保持一個looper),里面沒有數(shù)據(jù)的話就會把傳遞過來的boolean類型放到looper對象的參數(shù)中,然后設置到線程池里去運用。

getMainLooper方法,會鎖住looper類,然后返回當前正在使用的looper。

myLooper()方法,會從當前的threadlocal獲取內(nèi)容并進行返回。

showSlowLog(long threshold, long measureStart, long measureEnd,String what, Message msg)方法,傳遞過來的參數(shù)如果還在倒計時,那么就打印log并返回為true,打印的log內(nèi)容見下圖:在這里插入圖片描述

myLooper()方法,會獲取當前threadllocal里面的內(nèi)容進行return。

myQueue()方法,執(zhí)行mylooper方法獲取其mQueue變量進行retun。

Looper(boolean quitAllowed)方法,實例化的時候會把傳遞過來參數(shù)作為實例化MessageQueue的參數(shù),并且當前的線程會獲取當前的線程,表述的可能不太清晰看圖吧:
在這里插入圖片描述

isCurrentThread()方法,該方法會判斷l(xiāng)ooper當前的sThread常量和Thread.currentThread()返回的變量是否相等(==)

setMessageLogging(@Nullable Printer printer)方法,會把傳遞過來的Printer 賦值給當前l(fā)ooper的mLogging變量。Printer 的用法還請再看相關介紹~

quit()方法,執(zhí)行l(wèi)ooper當前queue的quit(blooean)方法,傳遞false過去。

quitSafely()方法,同樣執(zhí)行queue的quit方法,但是會傳遞true過去,至于這個方法傳遞不同參數(shù)的含義請到queue分析當中去看。

getThread()方法,return looper當前的mThread。

getQueue()方法,return looper當前的mQueue。

dump(@NonNull Printer pw, @NonNull String prefix) 方法,會用傳遞過來的pw打印出prefix內(nèi)容,然后執(zhí)行mqueue.dump方法,該方法第三個參數(shù)為null。

dump(@NonNull Printer pw, @NonNull String prefix, Handler handler)方法,會用傳遞過來的pw打印出prefix內(nèi)容,然后執(zhí)行mqueue.dump方法,該方法第三個參數(shù)為傳遞過來的handler。具體執(zhí)行內(nèi)容也請看queue里面的dump方法。(該方法為hide,寫多了)

toString()方法,這個就看圖片吧。
在這里插入圖片描述

prepareMainLooper()方法,會把false傳遞到要執(zhí)行的prepare方法中。然后synchronized-- looper類 判斷當前的looper是否為null,為null的話就走myLooper方法進行獲取,不為null則會拋出IllegalStateException。

loop方法內(nèi)容比較多,也需要結合代碼進行查看。先進行大概描述,然后再結合圖片里面的代碼進行查看。
looper.loop會先執(zhí)行myLooper方法獲取looper判斷是否為null。獲取當前l(fā)ooper的mQueue,進入到無限循環(huán)當中,獲取queue里面的message。如果message為null就return,不為null時就會獲取當前的observer,獲取當前message里面的相關時間和tag用來判斷message的執(zhí)行時間。把相關tag放到trace.tracebegin當中進行跟蹤。判斷當前observer是否為空不為空的話執(zhí)行相應方法,首先執(zhí)行messageDispatchStarting方法,在message.target執(zhí)行dispatchMessage之后執(zhí)行observer.messageDispatched方法,如果這個時候走到catch里面了,會執(zhí)行observer的dispatchingThrewException方法。trycatch最終都會跟蹤該消息。判斷時間打印出相應的log,最終會執(zhí)行message.recycleUnchecked()重置message 的內(nèi)容和Binder.clearCallingIdentity()方法清理標識。

public static void loop() {final Looper me = myLooper();
        if (me == null) {throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        if (me.mInLoop) {Slog.w(TAG, "Loop again would have the queued messages be executed"
                    + " before this one completed.");
        }

        me.mInLoop = true;
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", 0);

        boolean slowDeliveryDetected = false;

        for (;;) {Message msg = queue.next(); // might block
            if (msg == null) {// No message indicates that the message queue is quitting.
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            final Printer logging = me.mLogging;
            if (logging != null) {logging.println(">>>>>Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }
            // Make sure the observer won't change while processing a transaction.
            final Observer observer = sObserver;

            final long traceTag = me.mTraceTag;
            long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
            long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;
            if (thresholdOverride >0) {slowDispatchThresholdMs = thresholdOverride;
                slowDeliveryThresholdMs = thresholdOverride;
            }
            final boolean logSlowDelivery = (slowDeliveryThresholdMs >0) && (msg.when >0);
            final boolean logSlowDispatch = (slowDispatchThresholdMs >0);

            final boolean needStartTime = logSlowDelivery || logSlowDispatch;
            final boolean needEndTime = logSlowDispatch;

            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }

            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
            final long dispatchEnd;
            Object token = null;
            if (observer != null) {token = observer.messageDispatchStarting();
            }
            long origWorkSource = ThreadLocalWorkSource.setUid(msg.workSourceUid);
            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);
                }
            }
            if (logSlowDelivery) {if (slowDeliveryDetected) {if ((dispatchStart - msg.when)<= 10) {Slog.w(TAG, "Drained");
                        slowDeliveryDetected = false;
                    }
                } else {if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
                            msg)) {// Once we write a slow delivery log, suppress until the queue drains.
                        slowDeliveryDetected = true;
                    }
                }
            }
            if (logSlowDispatch) {showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg);
            }

            if (logging != null) {logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    }

至此looper對外暴露的方法基本都已經(jīng)寫出。

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧

本文標題:AndroidLooper用法及分析-創(chuàng)新互聯(lián)
網(wǎng)頁地址:http://www.rwnh.cn/article6/dcdoig.html

成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供建站公司、外貿(mào)網(wǎng)站建設、軟件開發(fā)、網(wǎng)站設計、網(wǎng)站設計公司、網(wǎng)站營銷

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉載內(nèi)容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設
怀远县| 行唐县| 突泉县| 定州市| 平潭县| 临西县| 双流县| 伊川县| 连南| 阿拉尔市| 博罗县| 峨山| 嘉义市| 凌源市| 鄱阳县| 枣阳市| 榆树市| 望城县| 出国| 宁国市| 宿松县| 华阴市| 汉中市| 兖州市| 报价| 寿光市| 吉安县| 唐河县| 温泉县| 牟定县| 米脂县| 宁河县| 华亭县| 麻阳| 维西| 通渭县| 阳春市| 湟源县| 会昌县| 雅江县| 嵊州市|