本文主要是介绍Handler机制浅析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用方法
实例化一个handler对象
val handler = object : Handler() {override fun handleMessage(msg: Message) {Log.e(TAG, "收到消息:" + msg.obj.toString())super.handleMessage(msg)}}
在需要发送消息的地方这样调用
val msg = Message()
msg.obj = "一条消息"
handler.sendMessage(msg)
打印日志
我们一般是在主线程创建handler,子线程发消息,比如我们可以这样写
object : Thread() {override fun run() {super.run()val msg = Message()msg.obj = "子线程消息"handler.sendMessage(msg)}}.start()
打印日志
有时候可能需要在子线程创建handler,主线程发消息,我们可能会这样写
class HandlerTestActivity : AppCompatActivity() {val TAG = "HandlerTestActivity"var handler:Handler?=nulloverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_handler_test)object : Thread() {override fun run() {super.run()Looper.prepare()handler = object : Handler() {override fun handleMessage(msg: Message) {Log.e(TAG, "收到消息:" + msg.obj.toString())super.handleMessage(msg)}}Looper.loop()}}.start()}//按钮点击事件,点击后发送消息fun sendMessage(view: View) {val msg = Message()msg.obj = "主线程消息"handler?.sendMessage(msg)}
}
运行代码后,点击按钮会得到如下报错
我们根据报错信息,到源码中寻找报错的原因,发现在Handler的构造方法中,有这个报错信息的代码
public Handler(@Nullable Callback callback, boolean async) {if (FIND_POTENTIAL_LEAKS) {final Class<? extends Handler> klass = getClass();if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());}}mLooper = Looper.myLooper();if (mLooper == null) {throw new RuntimeException("Can't create handler inside thread " + Thread.currentThread()+ " that has not called Looper.prepare()");}mQueue = mLooper.mQueue;mCallback = callback;mAsynchronous = async;}
可以看出,当mLooper为null时,就会抛出这个错误,mLooper是通过Looper.myLooper()获取的,
我们找到Looper.myLooper()方法
public static @Nullable Looper myLooper() {return sThreadLocal.get();}
发现是调用了sThreadLocal的get()方法获取的,而sThreadLocal是一个ThreadLocal对象,持有Looper的范型
@UnsupportedAppUsagestatic final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
他的get方法是这样的
public T get() {Thread t = Thread.currentThread();ThreadLocalMap map = getMap(t);if (map != null) {ThreadLocalMap.Entry e = map.getEntry(this);if (e != null) {@SuppressWarnings("unchecked")T result = (T)e.value;return result;}}return setInitialValue();}
简单点说,就是从一个Map里取出一个T对象,也就是上面的范型Looper
有get就有set,set方法是这样的
public void set(T value) {Thread
这篇关于Handler机制浅析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!