Handler消息传递机制类引入方法及执行流程是什么

发布时间:2023-04-13 16:59:14 作者:iii
来源:亿速云 阅读:422

Handler消息传递机制类引入方法及执行流程是什么

目录

  1. 引言
  2. Handler消息传递机制概述
  3. Handler消息传递机制的引入方法
  4. Handler消息传递机制的执行流程
  5. Handler消息传递机制的源码分析
  6. Handler消息传递机制的常见问题与解决方案
  7. 总结

引言

在Android开发中,Handler消息传递机制是一个非常重要的概念。它主要用于在不同线程之间进行通信,尤其是在主线程(UI线程)与子线程之间传递消息。理解Handler消息传递机制的引入方法及执行流程,对于开发高效、稳定的Android应用至关重要。本文将详细介绍Handler消息传递机制的引入方法、执行流程、源码分析以及常见问题与解决方案。

Handler消息传递机制概述

Handler消息传递机制是Android系统中用于线程间通信的一种机制。它主要由以下几个核心类组成:

通过Handler消息传递机制,开发者可以在不同的线程之间传递消息,从而实现线程间的通信和协作。

Handler消息传递机制的引入方法

在Activity中引入Handler

在Activity中引入Handler是最常见的场景。通常,我们会在Activity的onCreate()方法中初始化Handler,并在需要的地方使用它来发送和处理消息。

public class MainActivity extends AppCompatActivity {
    private Handler mHandler;

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

        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                // 处理消息
                switch (msg.what) {
                    case 1:
                        // 处理消息类型1
                        break;
                    case 2:
                        // 处理消息类型2
                        break;
                    default:
                        break;
                }
            }
        };

        // 发送消息
        mHandler.sendEmptyMessage(1);
    }
}

在Service中引入Handler

在Service中引入Handler的方式与在Activity中类似。我们可以在Service的onCreate()方法中初始化Handler,并在需要的地方使用它来发送和处理消息。

public class MyService extends Service {
    private Handler mHandler;

    @Override
    public void onCreate() {
        super.onCreate();
        mHandler = new Handler(Looper.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                // 处理消息
                switch (msg.what) {
                    case 1:
                        // 处理消息类型1
                        break;
                    case 2:
                        // 处理消息类型2
                        break;
                    default:
                        break;
                }
            }
        };

        // 发送消息
        mHandler.sendEmptyMessage(1);
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

在自定义线程中引入Handler

在自定义线程中引入Handler时,我们需要手动创建Looper并启动消息循环。通常,我们会在自定义线程的run()方法中初始化Looper和Handler。

public class MyThread extends Thread {
    private Handler mHandler;

    @Override
    public void run() {
        Looper.prepare(); // 初始化Looper
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // 处理消息
                switch (msg.what) {
                    case 1:
                        // 处理消息类型1
                        break;
                    case 2:
                        // 处理消息类型2
                        break;
                    default:
                        break;
                }
            }
        };

        Looper.loop(); // 启动消息循环
    }

    public Handler getHandler() {
        return mHandler;
    }
}

Handler消息传递机制的执行流程

消息的创建与发送

在Handler消息传递机制中,消息的创建与发送是通过Handler类来完成的。我们可以通过HandlerobtainMessage()方法获取一个Message对象,并通过sendMessage()方法将消息发送到消息队列中。

Message msg = mHandler.obtainMessage();
msg.what = 1; // 设置消息类型
msg.obj = "Hello, World!"; // 设置消息内容
mHandler.sendMessage(msg);

消息的存储与分发

消息的存储与分发是通过MessageQueueLooper来完成的。MessageQueue是一个消息队列,用于存储待处理的消息。Looper则负责从MessageQueue中取出消息,并将其分发给对应的Handler处理。

public 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;

    for (;;) {
        Message msg = queue.next(); // 从消息队列中取出消息
        if (msg == null) {
            return;
        }

        msg.target.dispatchMessage(msg); // 分发消息给对应的Handler处理
        msg.recycleUnchecked(); // 回收消息
    }
}

消息的处理

消息的处理是通过HandlerhandleMessage()方法来完成的。当LooperMessageQueue中取出消息后,会调用HandlerdispatchMessage()方法,最终将消息传递给handleMessage()方法进行处理。

public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg); // 调用handleMessage()方法处理消息
    }
}

Handler消息传递机制的源码分析

Handler类的源码分析

Handler类是Handler消息传递机制的核心类之一。它负责发送和处理消息。以下是Handler类的主要源码分析:

public class Handler {
    final Looper mLooper;
    final MessageQueue mQueue;
    final Callback mCallback;

    public Handler(Looper looper, Callback callback) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
    }

    public void handleMessage(Message msg) {
        // 处理消息
    }

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

    public final boolean sendMessage(Message msg) {
        return sendMessageDelayed(msg, 0);
    }

    public final boolean sendMessageDelayed(Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        return queue.enqueueMessage(msg, uptimeMillis);
    }
}

Looper类的源码分析

Looper类是Handler消息传递机制的另一个核心类。它负责管理消息队列,并循环取出消息分发给对应的Handler处理。以下是Looper类的主要源码分析:

public final class Looper {
    private static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    final MessageQueue mQueue;
    final Thread mThread;

    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

    public static Looper myLooper() {
        return sThreadLocal.get();
    }

    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;

        for (;;) {
            Message msg = queue.next(); // 从消息队列中取出消息
            if (msg == null) {
                return;
            }

            msg.target.dispatchMessage(msg); // 分发消息给对应的Handler处理
            msg.recycleUnchecked(); // 回收消息
        }
    }
}

MessageQueue类的源码分析

MessageQueue类是Handler消息传递机制中的消息队列类。它负责存储待处理的消息。以下是MessageQueue类的主要源码分析:

public final class MessageQueue {
    private long mPtr; // 指向native层的消息队列
    private boolean mQuitAllowed;

    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }

    boolean enqueueMessage(Message msg, long when) {
        synchronized (this) {
            msg.when = when;
            Message p = mMessages;
            if (p == null || when == 0 || when < p.when) {
                msg.next = p;
                mMessages = msg;
            } else {
                Message prev;
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                }
                msg.next = p;
                prev.next = msg;
            }
            return true;
        }
    }

    Message next() {
        for (;;) {
            synchronized (this) {
                Message msg = mMessages;
                if (msg != null) {
                    mMessages = msg.next;
                    return msg;
                }
            }
        }
    }
}

Handler消息传递机制的常见问题与解决方案

内存泄漏问题

在使用Handler时,如果Handler持有Activity的引用,而Activity已经被销毁,但Handler仍然持有其引用,就会导致内存泄漏。为了避免内存泄漏,我们可以使用静态内部类或弱引用来解决这个问题。

private static class MyHandler extends Handler {
    private final WeakReference<MainActivity> mActivity;

    MyHandler(MainActivity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MainActivity activity = mActivity.get();
        if (activity != null) {
            // 处理消息
        }
    }
}

消息处理延迟问题

在某些情况下,消息处理可能会延迟。这通常是由于消息队列中有大量消息等待处理,或者消息处理本身耗时较长。为了避免消息处理延迟,我们可以优化消息处理逻辑,或者使用HandlerThread来处理耗时操作。

HandlerThread handlerThread = new HandlerThread("MyHandlerThread");
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(new Runnable() {
    @Override
    public void run() {
        // 处理耗时操作
    }
});

消息丢失问题

在某些情况下,消息可能会丢失。这通常是由于消息队列已满,或者消息处理逻辑中出现了异常。为了避免消息丢失,我们可以增加消息队列的容量,或者在消息处理逻辑中添加异常处理机制。

try {
    // 处理消息
} catch (Exception e) {
    e.printStackTrace();
}

总结

Handler消息传递机制是Android开发中非常重要的一个概念。通过理解Handler消息传递机制的引入方法、执行流程、源码分析以及常见问题与解决方案,我们可以更好地开发高效、稳定的Android应用。希望本文能够帮助读者深入理解Handler消息传递机制,并在实际开发中灵活运用。

推荐阅读:
  1. SpringMVC框架如何实现Handler处理器
  2. 如何使用Flutter permission_handler权限插件

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

handler

上一篇:怎么使用element-ui设置table组件宽度为百分比

下一篇:提示信息控件AlertDialog对话框怎么使用

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》