Android源码分析 --- 消息机制

Android源码分析 — Hander消息机制

本篇记录Hanlder消息机制的关键节点代码

以下为源码:

Activity中的消息机制是在ActivityThread的main方法中初始化的,但注意的是ActivityThread并非继承字Thread。

    public static void main(String[] args) {
        SamplingProfilerIntegration.start();
        CloseGuard.setEnabled(false);
        Environment.initForCurrentUser();
        EventLogger.setReporter(new ActivityThread.EventLoggingReporter());
        Process.setArgV0("<pre-initialized>");
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        AsyncTask.init();
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

存储消息,handler将Message存放到MessageQueue中

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (this.mAsynchronous) {
            msg.setAsynchronous(true);
        }

        return queue.enqueueMessage(msg, uptimeMillis);
    }

具体的存入队列的方法,通过指明其next的值,指明message存入队列的位置

 final boolean enqueueMessage(Message msg, long when) {
        if (msg.isInUse()) {
            throw new AndroidRuntimeException(msg + " This message is already in use.");
        } else if (msg.target == null) {
            throw new AndroidRuntimeException("Message must have a target.");
        } else {
            boolean needWake;
            synchronized(this) {
                if (this.mQuiting) {
                    RuntimeException e = new RuntimeException(msg.target + " sending message to a Handler on a dead thread");
                    Log.w("MessageQueue", e.getMessage(), e);
                    return false;
                }

                msg.when = when;
                Message p = this.mMessages;
                if (p != null && when != 0L && when >= p.when) {
                    needWake = this.mBlocked && p.target == null && msg.isAsynchronous();

                    while(true) {
                        Message prev = p;
                        p = p.next;
                        if (p == null || when < p.when) {
                            msg.next = p;
                            prev.next = msg;
                            break;
                        }

                        if (needWake && p.isAsynchronous()) {
                            needWake = false;
                        }
                    }
                } else {
                    msg.next = p;
                    this.mMessages = msg;
                    needWake = this.mBlocked;
                }
            }

            if (needWake) {
                this.nativeWake(this.mPtr);
            }

            return true;
        }
    }

取消息,通过不断的循环从队列中取出消息,并根据message关联的target,也就是handler,将消息分发出去

 public static void loop() {
        Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        } else {
            MessageQueue queue = me.mQueue;
            Binder.clearCallingIdentity();
            long ident = Binder.clearCallingIdentity();

            while(true) {
                Message msg = queue.next();
                if (msg == null) {
                    return;
                }

                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);
                }

                long newIdent = Binder.clearCallingIdentity();
                if (ident != newIdent) {
                    Log.wtf("Looper", "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();
            }
        }
    }

那既然消息是在主线程不断的轮询读取的,而我们activity的生命周期都是在主线程执行的,为什么不会卡死

public void handleMessage(Message msg) {
            ActivityThread.ActivityClientRecord r;
            switch(msg.what) {
            case 100:
                Trace.traceBegin(64L, "activityStart");
                r = (ActivityThread.ActivityClientRecord)msg.obj;
                r.packageInfo = ActivityThread.this.getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo);
                ActivityThread.this.handleLaunchActivity(r, (Intent)null);
                Trace.traceEnd(64L);
                break;
            case 101:
                Trace.traceBegin(64L, "activityPause");
                ActivityThread.this.handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);
                this.maybeSnapshot();
                Trace.traceEnd(64L);
                break;
              .
              .
              .
            case 142:
                ActivityThread.this.handleUnstableProviderDied((IBinder)msg.obj, false);
            }

        }

因为activity的生命周期就是通过handler接收到的消息调用的,所以不会卡死

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值