安卓开发笔记——关于Handler的一些总结(上)

接上篇文章《安卓开发笔记——关于AsyncTask的使用》,今天来讲下在安卓开发里"重中之重"的另一个异步操作类Handler。

今天打算先讲下关于Handler的一些基本定义和使用方式

还是以一个下载图片为例,先看下实例效果:

好了,先来看下关于Handler的定义:

以上是官方对于Hanler类的描述,大致意思是说:Handler主要用于异步消息的处理:当发出一个消息之后,首先进入一个消息队列,发送消息的函数即刻返回,而另外一个部分在消息队列中逐一将消息取出,然后对消息进行处理,也就是发送消息和接收消息不是同步的处理。 这种机制通常用来处理相对耗时比较长的操作。

1、Handler是一套更新UI的机制,在子线程中进行耗时操作,然后通过它来通知主线程对UI进行更新。

2、Handler也是一套消息处理机制,可以用它来发送消息和处理消息。

关于Handler的用途:

Handler可以分发Message对象和Runnable对象到主线程中,每个Handler的实例都会绑定到创建他的线程中(一般是位于主线程)

用途:1、安排消息或Runnable 在某个主线程中某个地方执行  2、安排一个动作在不同的线程中执行

接下来讲讲Handler的基本使用方式,今天先不讲太复杂,不引入线程和消息队列的概念,等下篇文章来说。

先来个教科书版本的Handler使用方式:(注释很全)

 1 package com.example.handlertest_01;
 2
 3 import java.io.IOException;
 4
 5 import org.apache.http.HttpEntity;
 6 import org.apache.http.HttpResponse;
 7 import org.apache.http.client.ClientProtocolException;
 8 import org.apache.http.client.HttpClient;
 9 import org.apache.http.client.methods.HttpGet;
10 import org.apache.http.impl.client.DefaultHttpClient;
11 import org.apache.http.util.EntityUtils;
12
13 import android.app.Activity;
14 import android.app.ProgressDialog;
15 import android.graphics.Bitmap;
16 import android.graphics.BitmapFactory;
17 import android.os.Bundle;
18 import android.os.Handler;
19 import android.os.Message;
20 import android.view.View;
21 import android.view.View.OnClickListener;
22 import android.widget.Button;
23 import android.widget.ImageView;
24
25 public class MainActivity extends Activity {
26     //声明所使用控件
27     private ImageView imageView;
28     private Button button;
29     private ProgressDialog progressDialog;
30     private String path = "http://pic.baomihua.com/photos/201110/m_6_634545730007187500_16585344.jpg";//下载图片的资源地址
31
32     //创建一个Handler对象
33     private Handler handler = new Handler() {
34         public void handleMessage(android.os.Message msg) {
35                 byte[] data=(byte[]) msg.obj;//直接obj对象
36                 Bitmap bitmap=BitmapFactory.decodeByteArray(data, 0, data.length);
37                 progressDialog.dismiss();
38                 imageView.setImageBitmap(bitmap);
39         };
40     };
41
42     @Override
43     protected void onCreate(Bundle savedInstanceState) {
44         super.onCreate(savedInstanceState);
45         setContentView(R.layout.activity_main);
46         //对控件进行实例化,并设置相对应属性
47         imageView = (ImageView) findViewById(R.id.imageView);
48         button = (Button) findViewById(R.id.bt);
49         progressDialog=new ProgressDialog(this);
50         progressDialog.setTitle("当前任务");
51         progressDialog.setMessage("正在下载图片,请稍后..");
52
53         //给按钮绑定监听
54         button.setOnClickListener(new OnClickListener() {
55
56             @Override
57             public void onClick(View v) {
58                 progressDialog.show();
59                 new Thread(new MyThread()).start();//开辟一条子线程,执行该线程操作
60             }
61         });
62
63     }
64
65     // 继承Runnable接口,开辟新线程访问网络资源
66     public class MyThread implements Runnable {
67         @Override
68         public void run() {
69             HttpClient httpClient = new DefaultHttpClient();
70             HttpGet httpGet = new HttpGet(path);
71             try {
72                 HttpResponse httpResponse = httpClient.execute(httpGet);
73                 if (httpResponse.getStatusLine().getStatusCode() == 200) {
74                     // 访问成功
75                     HttpEntity entity = httpResponse.getEntity();
76                     // 阿帕奇提供的工具类EntityUtils可以很方便的把实体对象转换成字节码数组
77                     byte[] data = EntityUtils.toByteArray(entity);
78
79                     Message message = handler.obtainMessage();//取得Message消息对象
80                     message.obj = data;
81                     handler.sendMessage(message);//利用handler发送消息
82                 }
83             } catch (ClientProtocolException e) {
84                 e.printStackTrace();
85             } catch (IOException e) {
86                 e.printStackTrace();
87             }
88         }
89
90     }
91
92 }

这里的Message就是上文所提到的消息,这边有个特别需要主要的是如何得到一个Message的实例对象,官方不提倡我们直接new Message(),它提供了很多种方法让我们去获取,具体我们可以看下API文档:

Handler类:

Message类:

为什么不直接去new Message()对象,查看过源码的朋友可以发现,其实Message.obtain()或者是Handler.obtainMesssage()在源码里我们可以发现,Android给我们提供了一个消息池,这个消息池的大小为10而且加锁了,在我们调用这些方法的时候,系统会先去消息池里去取消息对象,如果不存在那么它才会去new出一个新的Message消息对象。

Message对象,里面除了给我们提供了obj这个存储对象之外,它还帮我们提供了一些其他类型的存储变量,比如:

这几个变量都是Android给我们提供的轻消耗的变量,我们可以拿来用,例如arg1,arg2我们可以用来存放简单的整型变量,what我们可以用来存放消息的标识符,然后在handMessgae(Message msg)里用一个switch去判断要执行那些操作等等,用法和上面给的代码一致。

例如:

1                     Message message=Message.obtain(handler);
2                     message.obj=data;
3                     message.sendToTarget();

具体大家查看下API结合我刚给的注释,其实都很简单,这里就不一一举例了。

最后再看看下几个发送消息的API:

说几个易混淆的吧,其他的大家可以自己尝试玩玩

比如sendMessageDelayed是延迟发送回消息,后面跟着long类型的时间,以毫秒为单位。

还有sendMessAtTime是定时发送消息,时间由uptimeMills()传递

这两句是等效的,都是延时1秒将消息加入列队:

1 handler.sendMessageAtTime(msg, SystemClock.uptimeMillis()+1000);
2 handler.sendMessageDelayed(msg, 1000);

好了,先介绍这么多吧,其他的等下篇文章再说。

时间: 2024-12-24 05:40:56

安卓开发笔记——关于Handler的一些总结(上)的相关文章

安卓 开发笔记目录

安卓 开发笔记index 安卓基础 Fragment总结 安卓 BroadcastReceiver笔记 安卓 Notification-通知总结 开源框架笔记 安卓 okhttp小结 EventBus框架总结 安卓 图片加载框架ImageLoader 第三方SDK 安卓 短信验证MobSMS集成 开源项目 其他 安卓 常用属性设置代码笔记 安卓 代码混淆与打包 AOSP开发笔记 开发工具 SecureCRT连接Ubuntu配置 Ubuntu开发环境搭建 开发环境 AOSP android7.1.

安卓开发笔记——丰富多彩的TextView

随手笔记,记录一些东西~ 记得之前写过一篇文章<安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html 文章里实现个性化TextView的主要方法是通过替换的方式,对关键字进行一些个性化处理,晚上再来补充一种实现方式. 老规矩,先看下效果图: 晚上带来的这种实现方式是通过Android官方给我们提供的Html类下面的fromHtml方法,这个方法可以对字符串进行HTML格式化,让TextView等一些

安卓开发笔记——打造属于自己的博客园APP(四)

在上篇文章<安卓开发笔记——打造属于自己的博客园APP(三)>中,我们对博客文章的详情页和评论页进行了实现,慢慢的一个APP已经出现雏形了,当然这只是完成了"表面效果",要真正做好一个APP并不是一件很轻松的事情,有很多细节需要我们一点一滴的去完善. 好了,来讲下今天要完成的效果,在优化了之前部分代码的前提下,今天来说下关于博客搜索和博客详情页的实现,依旧国际惯例,来看下效果图:(动态图片比较大,加载需要点时间) 效果比较简单,很多东西我们还是可以复用之前的代码,毕竟这种列

安卓开发笔记——自定义广告轮播Banner(无限循环实现)

关于广告轮播,大家肯定不会陌生,它在现手机市场各大APP出现的频率极高,它的优点在于"不占屏",可以仅用小小的固定空位来展示几个甚至几十个广告条,而且动态效果很好,具有很好的用户"友好性",下面来看几个示例图:     再来看下我仿写的效果: 关于广告轮播Banner这个东西,GitHub上面应该有现成的开源组件,不过我没去找过,觉得实现起来不会太难,就自己去仿写了,下面我说下实现的思路: 1.首先看到这个可以滑动切换图片的界面,我们很自然就会想到ViewPager

安卓开发笔记——多种方式实现底部菜单栏(仿微信界面)

关于底部菜单是什么,我想没必要介绍了,在市场上的APP里太常见了,这里提供两种方式来实现. 记得之前写过几篇关于底部菜单实现的方法,有兴趣的朋友可以看看: 1.<安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航)> 2.<安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航)> 3.<安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)> 今天带来种相对更通俗易懂的写法,不再和过去一样去沿用TabHost了

安卓开发笔记——高仿新浪微博文字处理(实现关键字高亮,自定义表情替换并加入点击事件实现)

先让大家看下效果图,这个是我自己在闲暇时间仿写的新浪微博客户端: 今天来讲讲如何实现上图的效果,这里需要用到SpannableString这个工具类,如果你对这个类并不熟悉,可以先看下我之前写的2篇文章: <安卓开发笔记——个性化TextView(新浪微博)>:http://www.cnblogs.com/lichenwei/p/4411607.html <安卓开发笔记——丰富多彩的TextView>:http://www.cnblogs.com/lichenwei/p/46120

安卓开发笔记——打造万能适配器(Adapter)

为什么要打造万能适配器? 在安卓开发中,用到ListView和GridView的地方实在是太多了,系统默认给我们提供的适配器(ArrayAdapter,SimpleAdapter)经常不能满足我们的需要,因此我们时常要去继承BaseAdapter类去实现一个自定义的适配器来满足我们的场景需要. 如果你是开发一个简单点的APP还好,可能ListView和GridView的数量不会太多,我们只要去写几个BaseAdapter实现类就可以了. 但如果有一天,你需要开发一个APP里面具有几十个ListV

安卓开发笔记——深入Activity

在上一篇文章<安卓开发笔记——重识Activity >中,我们了解了Activity生命周期的执行顺序和一些基本的数据保存操作,但如果只知道这些是对于我们的开发需求来说是远远不够的,今天我们继续探索Activity,来了解下关于Activity任务栈和Activity四种启动模式的区别. 为什么需要了解关于Activity的任务栈,其实最直接的体现就是提高用户交互友好性. 举个例子,当我们去浏览一个新闻客户端的时候,我们进入了新闻详情页,在这个页面有相隔两条的新闻标题,当我们去点击这个标题的时

安卓开发笔记——打造属于自己的博客园APP(二)

在上一篇文章<安卓开发笔记——打造属于自己的博客园APP(一)>中,我们基本上实现了博客园的主体UI框架(后面可能会有些小变化,等遇到了再说).今天来讲讲博客园首页模块的大体实现,国际惯例,先来看下效果图: 整体UI效果: 下拉刷新和上拉加载的动画效果: 在上篇文章中,我们定义的Tabs主题文字分别是(首页,精华,候选,推荐),这边的命名我是根据博客园网站首页的栏目来命名的,那时候我还没仔细看过博客园的开放接口,后来才发现原来博客园没有对应开放这些栏目的接口,博客园只开放了(文章列表,48小时