Android Handler使用

Android Handler使用

一、什么是Handler?Handler有什么用?
          Android中Handler是一个十分重要的东西,很多时候都需要用到Handler。为什么要用Handler呢?我们知道Android更新UIt的操作必须放到主线程中来进行,那么问题来了,假如你有现在需要下载一张图片并显示到Activity中,假如这张图片很大,需要下载很长时间。如果你直接放到Activity主线程中下载,那么会造成页面卡死(因为主线程一直在等下载图片完图片),我们知道,如果一个页面超过5S没有响应会发生ANR错误,因此你会想到开一个线程去下载图片,那么问题又来了,你下载完图片不能直接更新UI,怎么把你下载图片加载到主线程中呢?Handler就是来解决问题的,Handler是线程间通信传递数据的有力工具。
二、Handler运行机制
       在使用Handler之前,你必须先明确几个概念:Looper、Thread、Message、MessageQueue和Handler的运行机制。
       Thread--线程,程序运行的基本单位,这里不做介绍。我用汽车通过隧道为比喻说下Handler的运行机制:
       在主线程中其实是有一个消息队列(MessageQueue)存在的,这是一种先进先出的数据结构,你可以理解为一个公路上的一个隧道,公路上的汽车就相当于一个Message,每一辆汽车都有各自的一些属性,携带了不同的东西,Looper相当于隧道出口的收费站,对每一辆通过隧道的汽车进行识别和处理,最终交给Handler去根据汽车里面携带的东西做不同的处理。 
        主线程中会自动生成这样的一个消息队列,辅助线程中则没有。
 三、Hander 的使用方法
           搞懂了Handler的运行机制,使用Handler就很轻松了。
           线程中把要传递的数据封装到一个Message对象中,然后handler.sendMessage()方法放到Message队列,实例化Handler对象并重写handleMessage方法,对不同             的Message做不同处理
           我们拿一个从网络下载图片,显示到Activity中为例,看一下Handler的用法:
            在这个例子中我们实现的效果是点击下载按钮,开一个辅助线程下载图片,然后用Handler传递给主线程,并更新UI,显示这张图片。
           核心代码如下:
            package com.demo.zgp.handlerdemo;


import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;


import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;




public class MainActivity extends ActionBarActivity {
    private Button mButton;
    public int count = 0;
    private AlertDialog dialog;
    public  AlertDialog.Builder builder=null;
    private String imgPath = "http://f.hiphotos.baidu.com/image/w%3D2048/sign=05793c21bba1cd1105b675208d2ac9fc/43a7d933c895d14350ee3c3272f082025aaf0703.jpg";
    private ImageView mImageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dialog=new ProgressDialog(this);
        dialog.setTitle("提示:");
        dialog.setMessage("正在下载,请稍后...");
        dialog.setCancelable(false);
        mImageView=(ImageView)findViewById(R.id.imageview);
        mButton = (Button) findViewById(R.id.button);
        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new DownloadThread()).start();
                dialog.show();
            }
        });
    }
    class DownloadThread implements Runnable {
        @Override
        public void run() {
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet(imgPath);
            HttpResponse httpResponse = null;
            try {
                httpResponse = httpClient.execute(httpGet);
                if(200 == httpResponse.getStatusLine().getStatusCode()){
                    byte[] data = EntityUtils.toByteArray(httpResponse.getEntity());
                    // 这里的数据data我们必须发送给UI的主线程,所以我们通过Message的方式来做桥梁。
                    Message message = Message.obtain();
                    message.obj = data;
                    message.what = 1;
                    handler.sendMessage(message);
                }
            } catch (Exception e) {
                Message message=Message.obtain();
                Bundle bundle=new Bundle();
                bundle.putString("error","下载失败!");
                message.setData(bundle);
                message.what=2;
                handler.sendMessage(message);
            }
        }
    }


    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    byte[] data = (byte[])msg.obj;
                    Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                    mImageView.setImageBitmap(bitmap);
                    dialog.dismiss();
                    Toast.makeText(MainActivity.this,"下载成功!",Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    Toast.makeText(MainActivity.this,"下载失败!",Toast.LENGTH_SHORT).show();
                    break;
            }
            super.handleMessage(msg);
        }
    };


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }


    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }


        return super.onOptionsItemSelected(item);
    }
}
效果图如下:
  



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值