Message,Loop和Handler

最近在弄Android,因为不允许在主线程中直接发送http请求获取图片,就搞起了Handler,然后看了网上和书上的各种原理,嗯。。。道理我都懂,但感觉用起来还是懵懵哒,就跑去翻了api文档,然后这篇文章算是总结

正文之前先写两点声明:

1. Runnable大家都知道是Thread实现的接口,但是和线程好像又不太一样,不知道要翻译成什么合适,就直接写Runnable了。

2. 因为是Android的初学者,加上主要参考文档是纯英文的官方api,可能会出现一些错误,请同是Android萌新的小伙伴不要尽信,多多验证,也超级欢迎老司机们指正(虽然我觉得老司机不需要看这种文章啦)

正文开始

Message类

概述

api原文:Defines a message containing a description and arbitrary data object that can be sent to a Handler. This object contains two extra int fields and an extra object field that allow you to not do allocations in many cases.

大致意思就是说,这是一个可以传给Handler的变量类型,包含一个描述和任意数据。它可以直接储存两个int类型和一个Object类型的变量,不要额外配置(所谓额外配置是指使用setData(Bundle data) 和getData()方法)

public变量

Creator<Message> creator  Message的Creator,深挖起来又会牵出很多东西,而且好像不怎么用,先放着

int arg1,arg2 和Object obj 用来储存数据的变量,就是上面概述中说的可以直接储存的三个变量

Messager replyTo 用来储存对此消息的答复

int sendingUid Message的Uid

int what 用户定义的code 用于验证

构造方法

Message() 普通的无参构造,一般不用,Message获得实例通常使用下面的静态方法

public方法

先看静态方法,Message的静态方法都是用来获得实例的,只是传入的参数不同

static Message obtain()  获得一个新的Message实例

static Message obtain(Message orig)  获得一个新的Message实例,并复制orig这个Message的所有值,包括target(Handler)到这个新实例

另外还有obtain(Handler h),obtain(Handler h,int what),obtain(Handler h, Runnable callback),obtain(Handler h, int what,int arg1,int arg2, Object obj),obtain(Handler h, int what,int  arg1,int arg2),obtain(Handler h, int what, Object obj)

其中int what,int arg1,int arg2, Object obj对应public变量,就不多说了

Handler h 设置的是Message实例的target,Runnable callback是一个回调的Runnable,Message被处理后执行

获得实例后才可以使用的方法

void copyFrom(Message o)  复制Message o 不包括target

int describeContents()  获得这个Message实例中特殊变量集合的位掩码(没太懂,也不知道翻译的对不对,上原文Describe the kinds of special objects contained in this Parcelable instance's marshaled representation.)

Runnable getCallback() 获得回调的Runnable

Handler getTarget() 获得作为target的Handler

void setTarget(Handler target) 设置作为target的Handler

Bundle getData() 获得储存的数据,lazily create Bunddle(Bunddle是一种key-value类型,可以储存任何数据)

Bundle peekData() 获得储存的数据,not lazily create Bunddle

void setData(Bundle data)  储存数据

long getWhen()  获取发送给目标Handler的时间, 返回毫秒

boolean isAsynchronous() 返回是否异步

void setAsynchronous(boolean async) 设置是否异步

void recycle()  回收实例

void sendToTarget()  发送给目标Handler

String toString()  和其他变量类型一样的toString()

void writeToParcel(Parcel dest, int flags)  把这个实例写到一个包(Parcel)里

MessageQueue类

原文Low-level class holding the list of messages to be dispatched by a Looper. Messages are not added directly to a MessageQueue, but rather through Handler objects associated with the Looper

Message列表,由Looper处理,通常通过与Looper绑定的Handler添加消息而不是直接添加

也就是说这个类其实是不怎么直接操作的,方法基本都是和handler的交互,包括新建、删除、判断是否空闲等等,所以具体的方法不写了,贴个api页面链接好了

https://developer.android.google.cn/reference/android/os/MessageQueue

Looper类

Class used to run a message loop for a thread. Threads by default do not have a message loop associated with them; to create one, call prepare() in the thread that is to run the loop, and then loop() to have it process messages until the loop is stopped.

用来操作一个线程的消息的类,但线程本身并没有loop, 需要在线程里用prepare()方法创建,并用loop()方法运行

Most interaction with a message loop is through the Handler class.

通常通过Handler交换信息

api里面给了一个例子

class LooperThread extends Thread {
      public Handler mHandler;

      public void run() {
          Looper.prepare();

          mHandler = new Handler() {
              public void handleMessage(Message msg) {
                  // process incoming messages here
              }
          };

          Looper.loop();
      }
  }

public 方法

还是先看静态方法

static Looper getMainLooper()  获得主线程的looper

static void prepare() 初始化这个线程的looper

static void loop()  启动这个线程的looper

static Looper myLooper()  获得当前线程的looper

static MessageQueue myQueue()  获得当前线程的MessageQueue

static void prepareMainLooper() 初始化当前线程为一个looper 并将其作为主线程的looper

非静态方法

可以看到Looper 并不是new出来的,而是通过prepare方法在线程中初始化的,也即是说获得一个Looper,需要通过myLooper()方法,或者getMainLooper()方法

MessageQueue getQueue()  获得此looper的MessageQueue

Thread getThread() 获得此looper的线程

boolean isCurrentThread() 判断此looper是否对应当前线程

void quit()  立刻放弃(结束)此looper

void quitSafely()  安全的结束此looper(即在所有待处理消息处理完成后结束此looper,但延迟消息要在looper结束后才会处理,也就是说这个方法可能会影响延迟时间。另外调用此方法后将不能再传入新的消息。)

void setMessageLogging(Printer printer)  设置输出日志的方法

void dump(Priner pw, String prefix)  用于调试的方法

String toString()  大家都能toString

Handler类

A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue.

Handler可以发送消息(Message)和Runnable到对应线程的消息队列(MessageQueue),并且运行它们。每个Handler都会和创建它的线程以及该线程的消息队列绑定,创建之后即开始发送Message和Runnable到消息队列,并处理离开队列的Message和Runnable

There are two main uses for a Handler: (1) to schedule messages and runnables to be executed as some point in the future; and (2) to enqueue an action to be performed on a different thread than your own.

Handler有两个主要用途:(1)安排Message和Runnable的执行时间(2)将一个行为加入到其他线程的消息队列中

第一点很好理解,第二点根据后面的说明,应该是通过在A线程中调用B线程Handler的sendMessage(Message msg) 方法实现的

后面还有一大段原文,基本是方法相关的一些说明,就不粘过来了,直接上方法

先说一下interface Handler.Callback

这是Handler类里的一个内接口,api中的说明是实例化的时候如果不想自己实现Handler里的方法,可以使用这个接口,这里的方法指的是void handleMessage(Message msg)方法,这是在子类中必须重写的方法,用于接收信息,而 Handler.Callback 这个内接口的代码是这样的

public interface Callback {  
    public boolean handleMessage(Message msg);  
}  

也就是说,不写void handleMessage(Message msg)也可以,那就写一下boolean handleMessage(Message msg)吧,这个boolean返回值True if no further handling is desired,不需要进一步处理的时候返回true,这说明如果你只是需要不停地接收信息,那么 return false就可以了

构造方法

Handler()  创建一个与当前线程Looper绑定的Handler

Handler(Looper looper)  创建一个和looper绑定的Handler

Handler(Handler.Callback callback)  创建一个Handler,然而并不想写自己的handlerMessage

Handler(Looper looper, Handler.Callback callback)  创建一个Handler,并不想写自己的handlerMessage, 还要手动绑定Looper

public方法

静态方法

static Handler createAsync(Looper looper, Handler.Callback callback)  创建一个异步的handdler

static Handler createAsync(Looper looper)  同上,区别不说了

其他方法

void dispatchMessage(Message msg)  处理系统消息

void handleMessage(Message msg)  子类必须实现此方法来接收消息(Subclasses must implement this to receive messages.)就是用户自定义消息的处理方法

String getMessageName(Message message)  获得消息名称

final boolean sendEmptyMessage(int what)  发送空消息

final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)  定时发送空消息

final boolean sendEmptyMessageDelayed(int what, long dellayMillis)  延迟发送空消息

final boolean sendMessage(Message msg)  发送消息到队列末尾

final boolean sendMessageAtFrontOfQueue(Message msg)   发送消息到队列开头(此消息下一个执行)

boolean sendMessageAtTime(Message msg, long uptimeMillis)   定时发送消息

final boolean sendMessageDelayed(int what, long dellayMillis)  延迟发送消息

final boolean post(Runnable r)  发送Runnable

postAtFrontOfQueue(Runnable r)  发送Runnable到下一个执行位置

postAtTime(Rnnable r, long uptimeMillis)  定时发送Runnable

postAtTime(Rnnable r,Object token,  long uptimeMillis)  定时发送Runnable

postDelayed(Rnnable r, long uptimeMillis)  延迟发送Runnable

postDelayed(Rnnable r,Object token,  long uptimeMillis)  延迟发送Runnable

final boolean hasMessage(int what)  判断消息是否存在

final boolean hasMessage(int what, Object object)  判断消息是否存在

finnal void removeCallbacks(Runnable r)  删除Callback

finnal void removeCallbacks(Runnable r, Object token) 删除Callback

finnal void removeCallbacksAndMessages(Object token) 删除Callback和Message

finnal void removeMessages(int what)  删除消息

finnal void removeMessages(int what,Object obj)  删除消息

final Message obtainMessage() 获得一个新消息

final Message obtainMessage(int what, int arg1, int arg2)  根据参数获得消息

final Message obtainMessage(int what, int arg1, int arg2,Object obj)  根据参数获得消息

final Message obtainMessage(int what)  根据参数获得消息

到此这几个类就都结束了,关联大致是这样的吧

Message<——>Handler<——>MessageQueue<——>Looper<——>Thread

猜你喜欢

转载自blog.csdn.net/GrassEva/article/details/81116284