每一个Android程序都有一个主线程负责响应用户的操作事件和绘制UI界面,该线程也被称为UI线程。在主线程中不允许执行耗时的操作,这样会导致ANR。因此如果要执行耗时操作一般需要创建一个工作线程。
Android不允许在非主线程中执行更新UI的操作,这是因为Android的UI设计不是线程安全的,在非主线程中更新UI会抛出异常。
例如我要在网上下载一副图片并在窗口中显示。我需要创建一个线程下载图片,当图片下载好之后通知UI线程显示图片。现在问题出现了:工作线程如何告诉UI线程图片已经下载好了呢?工作线程如何和UI线程通信呢?
一种方法是这两个线程共享一个队列,当工作线程有更新UI的需求时,就把该需求封装成一个消息放入该队列中。UI线程循环的检测该队列中是否有消息,如果有的话就取出消息执行更新UI的操作。如果没有的话,UI线程当然也不能终止,它必须阻塞在这里一直等待。那UI线程如何响应用户的操作和绘制UI界面呢?这也简单把这些需求也放入队列中就可以了。
其实在UI线程和工作线程中确实存在这样一个阻塞队列。Handler就是用来向该队列放消息的。Handler不光可以向队列中放消息还可以提供如何处理消息的方法。在每个消息中都存在一个handler的引用。比如使用handlera 把消息a放入队列中则在消息a中就包含handlera 的引用。在处理消息时就取出消息a中的引用并调用handler提供的处理消息的方法。
Android源码中handler的实现思路大体就是这样,不过这里没有考虑很多细节的东西。android中把这一系列的东西封装的很好,能够非常方便的重用。
Android不允许在非主线程中执行更新UI的操作,这是因为Android的UI设计不是线程安全的,在非主线程中更新UI会抛出异常。
例如我要在网上下载一副图片并在窗口中显示。我需要创建一个线程下载图片,当图片下载好之后通知UI线程显示图片。现在问题出现了:工作线程如何告诉UI线程图片已经下载好了呢?工作线程如何和UI线程通信呢?
一种方法是这两个线程共享一个队列,当工作线程有更新UI的需求时,就把该需求封装成一个消息放入该队列中。UI线程循环的检测该队列中是否有消息,如果有的话就取出消息执行更新UI的操作。如果没有的话,UI线程当然也不能终止,它必须阻塞在这里一直等待。那UI线程如何响应用户的操作和绘制UI界面呢?这也简单把这些需求也放入队列中就可以了。
其实在UI线程和工作线程中确实存在这样一个阻塞队列。Handler就是用来向该队列放消息的。Handler不光可以向队列中放消息还可以提供如何处理消息的方法。在每个消息中都存在一个handler的引用。比如使用handlera 把消息a放入队列中则在消息a中就包含handlera 的引用。在处理消息时就取出消息a中的引用并调用handler提供的处理消息的方法。
Android源码中handler的实现思路大体就是这样,不过这里没有考虑很多细节的东西。android中把这一系列的东西封装的很好,能够非常方便的重用。