1、Message相关方法

1-1、Message相关成员变量

  • 每个 Message 都持有 Handler 实例。如果 Handler 持有Activity的引用,Activity onDestroy 后 Message 却仍然在队列中,因为 Handler 与Activity的强关联,会造成 Activity 无法被 GC 回收,导致内存泄露。 因此在Activity onDestroy 时,与Activity关联的Handler应清除它的队列由Activity产生的任务,避免内存泄露

    1. /**
    2. * 储存消息数据
    3. */
    4. public int what;
    5. public int arg1;
    6. public int arg2;
    7. public Object obj;
    8. /**
    9. * 每个消息持有Handler实例
    10. */
    11. Handler target;
    12. /**
    13. * 消息自带的callback
    14. */
    15. Runnable callback;
    16. /**
    17. * 下一个消息,所有消息组成一个链表
    18. */
    19. android.os.Message next;

    1-2、回收消息

    1. /**
    2. * 释放Message避免引用Handler导致内存泄漏
    3. */
    4. public void recycle() {
    5. if (isInUse()) {
    6. if (gCheckRecycle) {
    7. throw new IllegalStateException("This message cannot be recycled because it "
    8. + "is still in use.");
    9. }
    10. return;
    11. }
    12. recycleUnchecked();
    13. }
    14. void recycleUnchecked() {
    15. // Mark the message as in use while it remains in the recycled object pool.
    16. // Clear out all other details.
    17. flags = FLAG_IN_USE;
    18. what = 0;
    19. arg1 = 0;
    20. arg2 = 0;
    21. obj = null;
    22. replyTo = null;
    23. sendingUid = UID_NONE;
    24. workSourceUid = UID_NONE;
    25. when = 0;
    26. target = null;
    27. callback = null;
    28. data = null;
    29. synchronized (sPoolSync) {
    30. if (sPoolSize < MAX_POOL_SIZE) {
    31. next = sPool;
    32. sPool = this;
    33. sPoolSize++;
    34. }
    35. }
    36. }

    1-3、创建消息

  • 获取实例最好的办法是调用Message.obtain()或Handler.obtainMessage()。这样可以从他们的可回收对象池中获取到消息实例

    1. /**
    2. * 从回收对象池中获取一个消息实例
    3. * @return
    4. */
    5. public static android.os.Message obtain() {
    6. synchronized (sPoolSync) {
    7. if (sPool != null) {
    8. android.os.Message m = sPool;
    9. sPool = m.next;
    10. m.next = null;
    11. m.flags = 0; // clear in-use flag
    12. sPoolSize--;
    13. return m;
    14. }
    15. }
    16. return new android.os.Message();
    17. }
    18. public static android.os.Message obtain(Handler h) {
    19. android.os.Message m = obtain();
    20. m.target = h;
    21. return m;
    22. }
    23. public static android.os.Message obtain(Handler h, Runnable callback) {
    24. android.os.Message m = obtain();
    25. m.target = h;
    26. m.callback = callback;
    27. return m;
    28. }

    1-4、发送消息

  • Message自己也有发送消息的方法,但其实还是调用了Handler的发送消息方法

    1. /**
    2. * 发送消息 target其实就是Handler
    3. */
    4. public void sendToTarget() {
    5. target.sendMessage(this);
    6. }

    2、Message简化源码

    ``` public final class Message implements Parcelable {

    /**

    • 储存消息数据 */ public int what; public int arg1; public int arg2; public Object obj;

      /**

    • 每个消息持有Handler实例 */ Handler target;

      /**

    • 消息自带的callback */ Runnable callback;

      /**

    • 下一个消息,所有消息组成一个链表 */ android.os.Message next;
  1. /**
  2. * 从回收对象池中获取一个消息实例
  3. * @return
  4. */
  5. public static android.os.Message obtain() {
  6. synchronized (sPoolSync) {
  7. if (sPool != null) {
  8. android.os.Message m = sPool;
  9. sPool = m.next;
  10. m.next = null;
  11. m.flags = 0; // clear in-use flag
  12. sPoolSize--;
  13. return m;
  14. }
  15. }
  16. return new android.os.Message();
  17. }
  18. public static android.os.Message obtain(Handler h) {
  19. android.os.Message m = obtain();
  20. m.target = h;
  21. return m;
  22. }
  23. public static android.os.Message obtain(Handler h, Runnable callback) {
  24. android.os.Message m = obtain();
  25. m.target = h;
  26. m.callback = callback;
  27. return m;
  28. }
  29. /**
  30. * 释放Message避免引用Handler导致内存泄漏
  31. */
  32. public void recycle() {
  33. if (isInUse()) {
  34. if (gCheckRecycle) {
  35. throw new IllegalStateException("This message cannot be recycled because it "
  36. + "is still in use.");
  37. }
  38. return;
  39. }
  40. recycleUnchecked();
  41. }
  42. void recycleUnchecked() {
  43. // Mark the message as in use while it remains in the recycled object pool.
  44. // Clear out all other details.
  45. flags = FLAG_IN_USE;
  46. what = 0;
  47. arg1 = 0;
  48. arg2 = 0;
  49. obj = null;
  50. replyTo = null;
  51. sendingUid = UID_NONE;
  52. workSourceUid = UID_NONE;
  53. when = 0;
  54. target = null;
  55. callback = null;
  56. data = null;
  57. synchronized (sPoolSync) {
  58. if (sPoolSize < MAX_POOL_SIZE) {
  59. next = sPool;
  60. sPool = this;
  61. sPoolSize++;
  62. }
  63. }
  64. }
  65. /**
  66. * 发送消息 target其实就是Handler
  67. */
  68. public void sendToTarget() {
  69. target.sendMessage(this);
  70. }

} ```