zoukankan      html  css  js  c++  java
  • 安卓开发笔记——关于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给我们提供了一个消息池,这个消息池的大小为50而且加锁了,在我们调用这些方法的时候,系统会先去消息池里去取消息对象,如果不存在那么它才会去new出一个新的Message消息对象。

    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);

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

  • 相关阅读:
    ansible-palybook剧本
    ansible服务的部署与使用
    keepalived实现nginx高可用
    Linux下通过uptime判断负载情况
    2个无线路由器怎么连接
    Delphi FastReport动态加载图片 (转载)
    SQLite 日期 & 时间
    SuperObject使用
    php int 与 datetime 转换
    sqlserver 2005/2008 导入超大sql文件
  • 原文地址:https://www.cnblogs.com/lichenwei/p/4399838.html
Copyright © 2011-2022 走看看