android 后台加载数据,【移动开发】Android中异步加载数据(一)Handler + Thread

在我们开发当中很多时候都会遇到:从网络上获取数据的操作或大量的IO数据操作时,会耗费很长时间,为了使用户的体验效果更好,现在大多数开发者都会使用异步的方式去处理这些的操作,异步的方式有好多种,在此我汇总了以下两种:

1.Handler + Thread的方式

2.AsyncTask异步更新UI界面

这两种方式各自有各自的优缺点,这里先介绍一下第一种方式

1.Hanlder介绍:

官方文档:

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.

一个处理程序允许你发送和处理消息或者Runnable对象关联到的一个线程的MessageQueue。每个处理程序的实例相关联着一个单个线程和一个线程的消息队列。当你创建一个新的处理程序,它被绑定到线程/消息队列的线程时创建它——从那时起,它将提供消息和runnables给消息队列和执行他们出来的消息队列。

Handler主要方法:

常用方法解释

(int what,Objectobj)获取一个Message对象,包含了一个标识和value

将Runnable r添加到消息队列,之后会被UI线程执行

(Runnabler, long delayMillis)延迟多少毫秒之后,再将该线程加入到消息队列中

添加一条消息到消息队列的末尾

简单的说Android采用UI单线程模型,所以只能在主线程中对UI元素进行操作。如果在非UI线程直接对UI进行了操作,就会报错,当然为了提高效率,Android为我们提供了消息循环的机制,我们可以利用这个机制来实现线程间的通信,在非UI线程发送消息到UI线程,最终让Ui线程来进行ui的操作

2.在非UI线程中发送消息通知UI线程更新界面:

import java.io.InputStream;

import java.net.HttpURLConnection;

import java.net.URL;

import android.os.Bundle;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

import android.widget.Toast;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

/**

* Handler + Thread 实现异步加载图片

* @author ZHF

*

*/

public class MainActivity extends Activity {

private static final int MSG_SUCCESS = 0;//成功获取图片

private static final int MSG_FAILURE = 1;//获取图片失败

public static final String IMG_URL = "http://p_w_picpaths.51cto.com/p_w_picpaths/index/Images/Logo.gi";

Button btn_handler;

ImageView p_w_picpathView;

private DownloadImgThread downloadImgThread;

private Handler mHandler = new Handler(){

public void handleMessage(Message msg) { //该方法是在UI主线程中执行

switch(msg.what) {

case MSG_SUCCESS:

p_w_picpathView.setImageBitmap((Bitmap)msg.obj); //显示图片

break;

case MSG_FAILURE:

Toast.makeText(MainActivity.this, "获取图片失败", Toast.LENGTH_LONG);

break;

}

};

};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

p_w_picpathView = (ImageView) this.findViewById(R.id.p_w_picpathView);

btn_handler = (Button) this.findViewById(R.id.btn_handler);

btn_handler.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

//开启一个非UI线程,用于下载图片

downloadImgThread = new DownloadImgThread();

downloadImgThread.start();

}

});

}

/**图片下载线程**/

private class DownloadImgThread extends Thread{

HttpURLConnection conn;

InputStream inputStream;

Bitmap imgBitmap;

@Override

public void run() {

try {

URL url = new URL(IMG_URL);

if(url != null) {

HttpURLConnection connection = (HttpURLConnection) url.openConnection();

connection.setConnectTimeout(2000);

connection.setDoInput(true);

connection.setRequestMethod("GET");

int code = connection.getResponseCode();

if(200 == code) {

inputStream = connection.getInputStream();

imgBitmap = BitmapFactory.decodeStream(inputStream);

//获取图片成功,向ui线程发送MSG_SUCCESS标识和bitmap对象

mHandler.obtainMessage(MSG_SUCCESS,imgBitmap).sendToTarget();

}else {

//获取图片失败,向ui线程发送MSG_FAILURE

mHandler.obtainMessage(MSG_FAILURE).sendToTarget();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

在自己的线程中获取到imgBitmap,不能直接p_w_picpathView.setImageBitmap(imgBitmap),会报错的哦! 通过Message中obj将其存储起来,传递到UI线程中再对其操作。

权限:

2.View的post(Runnable r)方法

在获取到imgBitmap之后,可以通过下面代码实现UI界面的更新哦:

//另外一种更简洁的发送消息给ui线程的方法。

mImageView.post(new Runnable() {

@Override

public void run() {//run()方法会在ui线程执行

mImageView.setImageBitmap(bm);

}

});

这是为什么那?

因为Android框架为每个应用的主线程创建了一个隐式的handler,使用post方法的原理就是给这个隐式的handler发送一个Runnable对象,然后隐式的handler会在ui线程执行Runnable对象的run()方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值