Android重难点解析
  • 前言
  • Handler机制
    • Handler、Looper、MessageQueue的关系是什么?
    • Looper、Thread、ThreadLoacal的关系是什么?
    • Message如何被分发到Handler.handlerMessage()?
    • Message是如何实现复用的?
    • FrameWork中哪些模块用到了Handler机制?
    • 使用Handler的正确姿势是什么?
    • 总结
  • Activity机制
    • Launcher是如何实现开启一个App的?
    • Activity在各种状态下的生命周期
    • Activity与Window是什么关系?
    • setContentView()之后是如何实现界面显示的?
  • View机制
    • ViewGroup和子View在测量、布局、绘制的先后顺序是什么?
    • 从startActivity()到UI对用户可见的过程中发生了什么事情?
    • Touch事件分发机制
  • 异步机制
    • AsyncTask的版本变更之谜
    • AsyncTask的实现原理
    • Picasso是如何实现异步加载图片的?
    • HandlerThread和IntentService
  • 内存管理机制
    • 如何防止发生内存泄露?
    • 如何发现内存泄露?
    • Java内存回收机制
    • 如何防止OOM?
  • Java基础
    • 线程同步
  • Android系统机制
    • zygote是什么
    • SystemServer是什么?
    • ActivityManagerService是什么?有什么作用?
    • App的主线程消息队列是何时建立的?
    • 为什么选择Binder作为Android的进程间通讯方式?
  • WebView机制
    • 如何避免WebView造成的内存泄露?
  • 数据持久化机制
    • ContentProvider的权限控制
    • ContentProvider的CRUL操作为什么需要线程同步?
    • 文件缓存应该放在哪里?
    • SharedPreferences在使用时有哪些注意事项?
    • 如何优化Sqlite数据库的操作?
  • Fragment机制
    • 如何解决Fragment重叠的问题?
    • Fragment的完整生命周期
  • Framework重难点
    • 如何理解Zygote和ServerManager这两个进程?
  • 单元测试
    • 为什么写单元测试?
Powered by GitBook
On this page

Was this helpful?

  1. Handler机制

Message是如何实现复用的?

为了提高效率,我们通常可以通过Handler.obtainMessage()来获取一个Message,实际是通过下面获取的。

frameworks/base/core/java/android/os/Handler.java

public final Message obtainMessage(){
    return Message.obtain(this);
}

frameworks/base/core/java/android/os/Message.java

public static Message obtain(Handler h) {
        Message m = obtain();
        m.target = h;
        return m;
    }

public static Message obtain() {
        synchronized (sPoolSync) {
            if (sPool != null) {
                Message m = sPool;
                sPool = m.next;
                m.next = null;
                m.flags = 0; // clear in-use flag
                sPoolSize--;
                return m;
            }
        }
        return new Message();
    }

Message除了可以作为发送信息的载体之外,其内部还维持了一个最大容量为50的单链表结构作为缓存池。

frameworks/base/core/java/android/os/Message.java

    private static final Object sPoolSync = new Object();
    private static Message sPool;
    private static int sPoolSize = 0;
    private static final int MAX_POOL_SIZE = 50;

因为这些都是静态变量,所以Message缓存池的概念在整个程序里面只有一个。

由于Message.obtian()的调用存在多个线程之间同时访问静态变量的数据共享问题,所以需要对方法块进行同步操作。从上面的代码中可以很清楚的看到对单链表的操作,如果存在缓存Message的话,就取出Header Message,并将Header指向Header.next。

那么sPool是在什么时候添加进Message的呢?

在Looper.loop()中,如果Message被处理之后,会调用下面的方法,完成数据的初始化和添加进缓存池的操作:

frameworks/base/core/java/android/os/Looper.java

 public static void loop() {
    ...
    msg.target.dispatchMessage(msg);
    msg.recycleUnchecked();
 }

frameworks./base/core/java/android/os/Message.java

 void recycleUnchecked() {
        // Mark the message as in use while it remains in the recycled object pool.
        // Clear out all other details.
        flags = FLAG_IN_USE;
        what = 0;
        arg1 = 0;
        arg2 = 0;
        obj = null;
        replyTo = null;
        sendingUid = -1;
        when = 0;
        target = null;
        callback = null;
        data = null;

        synchronized (sPoolSync) {
            if (sPoolSize < MAX_POOL_SIZE) {
                next = sPool;
                sPool = this;
                sPoolSize++;
            }
        }
    }

因此,通过这种机制就完成了Message的缓存池功能,提高了效率。

PreviousMessage如何被分发到Handler.handlerMessage()?NextFrameWork中哪些模块用到了Handler机制?

Last updated 6 years ago

Was this helpful?