[转载]安卓开发笔记——关于Handler的一些总结(上) – Balla_兔子 – 博客园.今天来讲下在安卓开发里”重中之重”的另一个异步操作类Handler。
今天打算先讲下关于Handler的一些基本定义和使用方式
还是以一个下载图片为例,先看下实例效果:
好了,先来看下关于Handler的定义:
以上是官方对于Hanler类的描述,大致意思是说:Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息 的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。
1、Handler是一套更新UI的机制,在子线程中进行耗时操作,然后通过它来通知主线程对UI进行更新。
2、Handler也是一套消息处理机制,可以用它来发送消息和处理消息。
关于Handler的用途:
Handler可以分发Message对象和Runnable对象到主线程中,每个Handler的实例都会绑定到创建他的线程中(一般是位于主线程)
用途:1、安排消息或Runnable 在某个主线程中某个地方执行 2、安排一个动作在不同的线程中执行
接下来讲讲Handler的基本使用方式,今天先不讲太复杂,不引入线程和消息队列的概念,等下篇文章来说。
先来个教科书版本的Handler使用方式:(注释很全)
<span class = "kwd" > package </span><span class = "pln" > com</span><span class = "pun" >.</span><span class = "pln" >example</span><span class = "pun" >.</span><span class = "pln" >handlertest_01</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > java</span><span class = "pun" >.</span><span class = "pln" >io</span><span class = "pun" >.</span><span class = "typ" >IOException</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "typ" >HttpEntity</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "typ" >HttpResponse</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "pln" >client</span><span class = "pun" >.</span><span class = "typ" >ClientProtocolException</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "pln" >client</span><span class = "pun" >.</span><span class = "typ" >HttpClient</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "pln" >client</span><span class = "pun" >.</span><span class = "pln" >methods</span><span class = "pun" >.</span><span class = "typ" >HttpGet</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "pln" >impl</span><span class = "pun" >.</span><span class = "pln" >client</span><span class = "pun" >.</span><span class = "typ" >DefaultHttpClient</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > org</span><span class = "pun" >.</span><span class = "pln" >apache</span><span class = "pun" >.</span><span class = "pln" >http</span><span class = "pun" >.</span><span class = "pln" >util</span><span class = "pun" >.</span><span class = "typ" >EntityUtils</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >app</span><span class = "pun" >.</span><span class = "typ" >Activity</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >app</span><span class = "pun" >.</span><span class = "typ" >ProgressDialog</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >graphics</span><span class = "pun" >.</span><span class = "typ" >Bitmap</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >graphics</span><span class = "pun" >.</span><span class = "typ" >BitmapFactory</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >os</span><span class = "pun" >.</span><span class = "typ" >Bundle</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >os</span><span class = "pun" >.</span><span class = "typ" >Handler</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >os</span><span class = "pun" >.</span><span class = "typ" >Message</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >view</span><span class = "pun" >.</span><span class = "typ" >View</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >view</span><span class = "pun" >.</span><span class = "typ" >View</span><span class = "pun" >.</span><span class = "typ" >OnClickListener</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >widget</span><span class = "pun" >.</span><span class = "typ" >Button</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > import </span><span class = "pln" > android</span><span class = "pun" >.</span><span class = "pln" >widget</span><span class = "pun" >.</span><span class = "typ" >ImageView</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >MainActivity</span><span class = "pln" > </span><span class = "kwd" > extends </span><span class = "pln" > </span><span class = "typ" >Activity</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > //声明所使用控件</span><span class="pln"> </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >ImageView</span><span class = "pln" > imageView</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >Button</span><span class = "pln" > button</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >ProgressDialog</span><span class = "pln" > progressDialog</span><span class = "pun" >;</span><span class = "pln" > </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >String</span><span class = "pln" > path </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "str" > "http://pic.baomihua.com/photos/201110/m_6_634545730007187500_16585344.jpg" </span><span class = "pun" >;</span><span class = "com" >//下载图片的资源地址</span><span class = "pln" > </span><span class = "com" > //创建一个Handler对象</span><span class="pln"> </span><span class = "kwd" > private </span><span class = "pln" > </span><span class = "typ" >Handler</span><span class = "pln" > handler </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Handler</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > handleMessage</span><span class = "pun" >(</span><span class = "pln" >android</span><span class = "pun" >.</span><span class = "pln" >os</span><span class = "pun" >.</span><span class = "typ" >Message</span><span class = "pln" > msg</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > byte </span><span class = "pun" >[]</span><span class = "pln" > data</span><span class = "pun" >=(</span><span class = "kwd" > byte </span><span class = "pun" >[])</span><span class = "pln" > msg</span><span class = "pun" >.</span><span class = "pln" >obj</span><span class = "pun" >;</span><span class = "com" > //直接obj对象</span><span class="pln"> </span><span class = "typ" >Bitmap</span><span class = "pln" > bitmap</span><span class = "pun" >=</span><span class = "typ" >BitmapFactory</span><span class = "pun" >.</span><span class = "pln" >decodeByteArray</span><span class = "pun" >(</span><span class = "pln" >data</span><span class = "pun" >,</span><span class = "pln" > </span><span class = "lit" > 0 </span><span class = "pun" >,</span><span class = "pln" > data</span><span class = "pun" >.</span><span class = "pln" >length</span><span class = "pun" >);</span><span class = "pln" > progressDialog</span><span class = "pun" >.</span><span class = "pln" >dismiss</span><span class = "pun" >();</span><span class = "pln" > imageView</span><span class = "pun" >.</span><span class = "pln" >setImageBitmap</span><span class = "pun" >(</span><span class = "pln" >bitmap</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "pun" >};</span><span class = "pln" > </span><span class = "pun" >};</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > protected </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > onCreate</span><span class = "pun" >(</span><span class = "typ" >Bundle</span><span class = "pln" > savedInstanceState</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "kwd" > super </span><span class = "pun" >.</span><span class = "pln" >onCreate</span><span class = "pun" >(</span><span class = "pln" >savedInstanceState</span><span class = "pun" >);</span><span class = "pln" > setContentView</span><span class = "pun" >(</span><span class = "pln" >R</span><span class = "pun" >.</span><span class = "pln" >layout</span><span class = "pun" >.</span><span class = "pln" >activity_main</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "com" > //对控件进行实例化,并设置相对应属性</span><span class="pln"> imageView </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >ImageView</span><span class = "pun" >)</span><span class = "pln" > findViewById</span><span class = "pun" >(</span><span class = "pln" >R</span><span class = "pun" >.</span><span class = "pln" >id</span><span class = "pun" >.</span><span class = "pln" >imageView</span><span class = "pun" >);</span><span class = "pln" > button </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >Button</span><span class = "pun" >)</span><span class = "pln" > findViewById</span><span class = "pun" >(</span><span class = "pln" >R</span><span class = "pun" >.</span><span class = "pln" >id</span><span class = "pun" >.</span><span class = "pln" >bt</span><span class = "pun" >);</span><span class = "pln" > progressDialog</span><span class = "pun" >=</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >ProgressDialog</span><span class = "pun" >(</span><span class = "kwd" > this </span><span class = "pun" >);</span><span class = "pln" > progressDialog</span><span class = "pun" >.</span><span class = "pln" >setTitle</span><span class = "pun" >(</span><span class = "str" > "当前任务" </span><span class = "pun" >);</span><span class = "pln" > progressDialog</span><span class = "pun" >.</span><span class = "pln" >setMessage</span><span class = "pun" >(</span><span class = "str" > "正在下载图片,请稍后.." </span><span class = "pun" >);</span><span class = "pln" > </span><span class = "com" > //给按钮绑定监听</span><span class="pln"> button</span><span class = "pun" >.</span><span class = "pln" >setOnClickListener</span><span class = "pun" >(</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >OnClickListener</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > onClick</span><span class = "pun" >(</span><span class = "typ" >View</span><span class = "pln" > v</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > progressDialog</span><span class = "pun" >.</span><span class = "pln" >show</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >Thread</span><span class = "pun" >(</span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >MyThread</span><span class = "pun" >()).</span><span class = "pln" >start</span><span class = "pun" >();</span><span class = "com" > //开辟一条子线程,执行该线程操作</span><span class="pln"> </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >});</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "com" > // 继承Runnable接口,开辟新线程访问网络资源</span><span class="pln"> </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > class </span><span class = "pln" > </span><span class = "typ" >MyThread</span><span class = "pln" > </span><span class = "kwd" > implements </span><span class = "pln" > </span><span class = "typ" >Runnable</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "lit" > @Override </span><span class = "pln" > </span><span class = "kwd" > public </span><span class = "pln" > </span><span class = "kwd" > void </span><span class = "pln" > run</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >HttpClient</span><span class = "pln" > httpClient </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >DefaultHttpClient</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "typ" >HttpGet</span><span class = "pln" > httpGet </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "kwd" > new </span><span class = "pln" > </span><span class = "typ" >HttpGet</span><span class = "pun" >(</span><span class = "pln" >path</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > try </span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "typ" >HttpResponse</span><span class = "pln" > httpResponse </span><span class = "pun" >=</span><span class = "pln" > httpClient</span><span class = "pun" >.</span><span class = "pln" >execute</span><span class = "pun" >(</span><span class = "pln" >httpGet</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "kwd" > if </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "pln" >httpResponse</span><span class = "pun" >.</span><span class = "pln" >getStatusLine</span><span class = "pun" >().</span><span class = "pln" >getStatusCode</span><span class = "pun" >()</span><span class = "pln" > </span><span class = "pun" >==</span><span class = "pln" > </span><span class = "lit" > 200 </span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > </span><span class = "com" > // 访问成功</span><span class="pln"> </span><span class = "typ" >HttpEntity</span><span class = "pln" > entity </span><span class = "pun" >=</span><span class = "pln" > httpResponse</span><span class = "pun" >.</span><span class = "pln" >getEntity</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "com" > // 阿帕奇提供的工具类EntityUtils可以很方便的把实体对象转换成字节码数组</span><span class="pln"> </span><span class = "kwd" > byte </span><span class = "pun" >[]</span><span class = "pln" > data </span><span class = "pun" >=</span><span class = "pln" > </span><span class = "typ" >EntityUtils</span><span class = "pun" >.</span><span class = "pln" >toByteArray</span><span class = "pun" >(</span><span class = "pln" >entity</span><span class = "pun" >);</span><span class = "pln" > </span><span class = "typ" >Message</span><span class = "pln" > message </span><span class = "pun" >=</span><span class = "pln" > handler</span><span class = "pun" >.</span><span class = "pln" >obtainMessage</span><span class = "pun" >();</span><span class = "com" > //取得Message消息对象</span><span class="pln"> message</span><span class = "pun" >.</span><span class = "pln" >obj </span><span class = "pun" >=</span><span class = "pln" > data</span><span class = "pun" >;</span><span class = "pln" > handler</span><span class = "pun" >.</span><span class = "pln" >sendMessage</span><span class = "pun" >(</span><span class = "pln" >message</span><span class = "pun" >);</span><span class = "com" > //利用handler发送消息</span><span class="pln"> </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > catch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >ClientProtocolException</span><span class = "pln" > e</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > e</span><span class = "pun" >.</span><span class = "pln" >printStackTrace</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "kwd" > catch </span><span class = "pln" > </span><span class = "pun" >(</span><span class = "typ" >IOException</span><span class = "pln" > e</span><span class = "pun" >)</span><span class = "pln" > </span><span class = "pun" >{</span><span class = "pln" > e</span><span class = "pun" >.</span><span class = "pln" >printStackTrace</span><span class = "pun" >();</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span><span class = "pln" > </span><span class = "pun" >}</span> |
这里的Message就是上文所提到的消息,这边有个特别需要主要的是如何得到一个Message的实例对象,官方不提倡我们直接new Message(),它提供了很多种方法让我们去获取,具体我们可以看下API文档:
Handler类:
Message类:
为什么不直接去new Message()对象,查看过源码的朋友可以发现,其实Message.obtain()或者是Handler.obtainMesssage()在源 码里我们可以发现,Android给我们提供了一个消息池,这个消息池的大小为10而且加锁了,在我们调用这些方法的时候,系统会先去消息池里去取消息对 象,如果不存在那么它才会去new出一个新的Message消息对象。
以上API这里再列举一个:
1 Message message=Message.obtain(handler); 2 message.obj=data; 3 message.sendToTarget();
都很简单,大家参照着API给的规范去做就可以了。
Message对象,里面除了给我们提供了obj这个存储对象之外,它还帮我们提供了一些其他类型的存储变量,比如:
这几个变量都是Android给我们提供的轻消耗的变量,我们可以拿来用,例如arg1,arg2我们可以用来存放简单的整型变量,what我们可 以用来存放消息的标识符,然后在handMessgae(Message msg)里用一个switch去判断要执行那些操作等等,用法和上面给的代码一致。
具体大家查看下API结合我刚给的注释,其实都很简单,这里就不一一举例了。
最后再看看下几个发送消息的API:
说几个易混淆的吧,其他的大家可以自己尝试玩玩
比如sendMessageDelayed是延迟发送回消息,后面跟着long类型的时间,以毫秒为单位。
还有sendMessAtTime是定时发送消息,时间由uptimeMills()传递
这两句是等效的,都是延时1秒将消息加入列队:
1 handler.sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000); 2 handler.sendMessageDelayed(msg, 1000);
好了,先介绍这么多吧,其他的等下篇文章再说。