亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

MessageQueue中死循環輪詢messeag沒發生ANR的原因猜想。

messageQueue輪詢消息是否存在及要傳遞給的target對象時,為什么沒發生ANR:個人猜想,當不存在在消息時,發生了循環阻塞,就像在socket編程中,當沒有客戶端訪問時,服務器端就阻塞在accept()方法中,當有消息需要處理時:循環繼續運行,不知道對不對。

正在回答

4 回答


? ? /**

? ? ?* Run the message queue in this thread. Be sure to call

? ? ?* {@link #quit()} to end the loop.

? ? ?*/

? ? public static void loop() {

? ? ? ? Looper me = myLooper();

? ? ? ? if (me == null) {

? ? ? ? ? ? throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");

? ? ? ? }

? ? ? ? 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();

? ? ? ??

? ? ? ? while (true) {

? ? ? ? ? ? Message msg = queue.next(); // might block

? ? ? ? ? ? if (msg != null) {

? ? ? ? ? ? ? ? if (msg.target == null) {

? ? ? ? ? ? ? ? ? ? // No target is a magic identifier for the quit message.

? ? ? ? ? ? ? ? ? ? return;

? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? long wallStart = 0;

? ? ? ? ? ? ? ? long threadStart = 0;


? ? ? ? ? ? ? ? // This must be in a local variable, in case a UI event sets the logger

? ? ? ? ? ? ? ? Printer logging = me.mLogging;

? ? ? ? ? ? ? ? if (logging != null) {

? ? ? ? ? ? ? ? ? ? logging.println(">>>>> Dispatching to " + msg.target + " " +

? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.callback + ": " + msg.what);

? ? ? ? ? ? ? ? ? ? wallStart = SystemClock.currentTimeMicro();

? ? ? ? ? ? ? ? ? ? threadStart = SystemClock.currentThreadTimeMicro();

? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? msg.target.dispatchMessage(msg);


? ? ? ? ? ? ? ? if (logging != null) {

? ? ? ? ? ? ? ? ? ? long wallTime = SystemClock.currentTimeMicro() - wallStart;

? ? ? ? ? ? ? ? ? ? long threadTime = SystemClock.currentThreadTimeMicro() - threadStart;


? ? ? ? ? ? ? ? ? ? logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);

? ? ? ? ? ? ? ? ? ? if (logging instanceof Profiler) {

? ? ? ? ? ? ? ? ? ? ? ? ((Profiler) logging).profile(msg, wallStart, wallTime,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? threadStart, threadTime);

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? // 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.recycle();

? ? ? ? ? ? }

? ? ? ? }

? ? }


0 回復 有任何疑惑可以回復我~
????/**
?????*?Run?the?message?queue?in?this?thread.?Be?sure?to?call
?????*?{@link?#quit()}?to?end?the?loop.
?????*/
????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;

????????//?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();

????????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
????????????Printer?logging?=?me.mLogging;
????????????if?(logging?!=?null)?{
????????????????logging.println(">>>>>?Dispatching?to?"?+?msg.target?+?"?"?+
????????????????????????msg.callback?+?":?"?+?msg.what);
????????????}

????????????msg.target.dispatchMessage(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.recycle();
????????}
????}


0 回復 有任何疑惑可以回復我~

Looper不斷輪詢MessageQueue,當取出msg時就會執行,如果該msg執行時間過長就會發生ANR。

1 回復 有任何疑惑可以回復我~

不錯,我也是這樣想的。如果發生阻塞,就會等待資源,進程實體有三個狀態,就緒,阻塞,執行。阻塞狀態就是等待資源

1 回復 有任何疑惑可以回復我~

舉報

0/150
提交
取消
Android面試??虷andler詳解
  • 參與學習       54867    人
  • 解答問題       192    個

學Android開發,必學Handler,也是Android面試常客

進入課程

MessageQueue中死循環輪詢messeag沒發生ANR的原因猜想。

我要回答 關注問題
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號