Android消息机制

本文详细探讨了Android消息机制,包括Handler的使用、ThreadLocal原理、MessageQueue与Looper的工作方式,以及Handler如何进行线程切换。重点分析了主线程为何不会卡死、多个Activity创建Handler的消息队列共享情况,同时还讨论了Handler可能导致的内存泄漏问题及其解决方案。
摘要由CSDN通过智能技术生成

文章参考:书籍 android开发艺术探索  

博客:https://www.jianshu.com/p/e172a2d58905

https://blog.csdn.net/qian520ao/article/details/78262289

前言

Android的消息机制主要指的就是Handler的运行机制,handler常被我们用来进行ui的修改。简单的说就是在子线程进行耗时操作,然后通过handler修改ui。

本文将从下面的几个方面来学习handler

基本的使用

要使用Handler我们需要创建一个Handler对象,同时为了能够处理我们自己发送的消息需要重写handleMessage方法。使用handlerf发送消息有两种方式 Handler.sendMessage() 和 Hanler.post()

下面我们就来看看handler的基本使用demo

public class HandlerDemoActivity extends AppCompatActivity {

    private final String TAG = getClass().getSimpleName();
    //继承Handler重写handleMessage方法处理自己的消息
    class MyHandler extends Handler{
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage( msg );
            Log.d( TAG,"接收到消息,可以更新ui" );
        }
    }

    Handler handler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_handler_demo );
        handler = new MyHandler();

        new Thread( new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep( 3000 );
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Message message = handler.obtainMessage( 1 );
                //使用sendMessage
                handler.sendMessage( message );
            }
        } ).start();

        new Thread( new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep( 3000 );
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //使用post
                handler.post( new Runnable() {
                    @Override
                    public void run() {
                        Log.d( TAG,"Runnable 执行,可以更新ui" );
                    }
                } );
            }
        } ).start();
    }



}

上面的demo就是Handler的基本使用。

ThreadLocal

根据Android开发艺术探索的说明:threadLocal是一个线程内部的数据存储类,通过它可以在指定线程中存储数据,数据存储后只能在指定线程获取。

demo验证:

public class ThreadLocalDemoActivity extends AppCompatActivity {
    private final String TAG = getClass().getSimpleName();

    ThreadLocal<Boolean> test = new ThreadLocal<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.activity_thread_local_demo );

        Log.d( TAG,"主线程: test "+test.get() );
        test.set( false );
        Log.d( TAG,"主线程: test "+test.get() );
        new Thread( new Runnable() {
            @Override
            public void run() {
                test.set( true );
                Log.d( TAG,"线程1: test "+test.get() );
            }
        } ).start();
        new Thread( new Runnable() {
            @Override
            public void run() {
                Log.d( TAG,"线程2: test "+test.get() );
            }
        } ).start();
    }
}

验证结果:

在主线程中第一次获取到的值是null,然后设置为false,主线程第二次获取为false。

在子线程1中开始就设置值为true,获取到的值为true

在子线程2中直接进行获取值为null。

验证了ThreadLocal只能在指定线程获取数据。

ThreadLocal原理

Thread内部维护着一个ThreadLocalMap:threadLocals对象,threadLocals在Thread中没有初始化。它的初始化来自ThreadLocal

我们来看看ThreadLocal的set方法

public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

getMap方法返回的就是当前线程维护的那个threadLocals对象,如果getMap返回对象不为空就以当前的ThreadLocal对象为key,将value放入threadLocals。如果为空那么就重新创建一个ThreadLocalMap并将值存放进去。我们这里不对ThreadLocalMap的具体存储过程进行分析。

ThreadLocal的get()方法

 public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = ma
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值