【移动开发】Android中异步加载数据(一)Handler + Thread
2013-07-18 15:40
671 查看
在我们开发当中很多时候都会遇到:从网络上获取数据的操作或大量的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主要方法:
简单的说Android采用UI单线程模型,所以只能在主线程中对UI元素进行操作。如果在非UI线程直接对UI进行了操作,就会报错,当然为了提高效率,Android为我们提供了消息循环的机制,我们可以利用这个机制来实现线程间的通信,在非UI线程发送消息到UI线程,最终让Ui线程来进行ui的操作
2.在非UI线程中发送消息通知UI线程更新界面:
权限:
2.View的post(Runnable r)方法
在获取到imgBitmap之后,可以通过下面代码实现UI界面的更新哦:
因为Android框架为每个应用的主线程创建了一个隐式的handler,使用post方法的原理就是给这个隐式的handler发送一个Runnable对象,然后隐式的handler会在ui线程执行Runnable对象的run()方法。
下一篇(AsyncTask):http://smallwoniu.blog.51cto.com/3911954/1252156
附件:http://down.51cto.com/data/2363167
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主要方法:
常用方法 | 解释 |
Message obtainMessage(int what, Object obj) | 获取一个Message对象,包含了一个标识和value |
boolean post(Runnable r) | 将Runnable r添加到消息队列,之后会被UI线程执行 |
boolean postDelayed(Runnable r, long delayMillis) | 延迟多少毫秒之后,再将该线程加入到消息队列中 |
boolean sendEmptyMessage(int what) | 发送一个只有标识的消息 |
boolean sendMessage(Message msg) | 添加一条消息到消息队列的末尾 |
void handleMessage(Message msg) | 用于处理接收到的消息 |
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://images.51cto.com/images/index/Images/Logo.gi"; Button btn_handler; ImageView imageView; private DownloadImgThread downloadImgThread; private Handler mHandler = new Handler(){ public void handleMessage(Message msg) { //该方法是在UI主线程中执行 switch(msg.what) { case MSG_SUCCESS: imageView.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); imageView = (ImageView) this.findViewById(R.id.imageView); 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,不能直接imageView.setImageBitmap(imgBitmap),会报错的哦! 通过Message中obj将其存储起来,传递到UI线程中再对其操作。
权限:
<uses-permission android:name="android.permission.INTERNET"/>
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()方法。
下一篇(AsyncTask):http://smallwoniu.blog.51cto.com/3911954/1252156
附件:http://down.51cto.com/data/2363167
相关文章推荐
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比--转载
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- 【移动开发】Android中异步加载数据(二)AsyncTask异步更新界面
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- Android异步加载数据更新UI(Thread+Handler)
- 【移动开发】Android图片异步加载之Android-Universal-Image-Loader使用 推荐
- Android开发之异步详解(一)Thread+Handler
- Android开发实现ListView异步加载数据的方法详解
- android开发异步加载网络数据AsyncTask的使用
- Android:ListView数据异步加载、Handler、AsyncTask
- 【移动开发】Android图片异步加载之Android-Universal-Image-Loader使用
- Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- Android通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比
- Android 异步加载数据 AsyncTask+Handler+AsyncHttpClient+Universal_Image_loader+Volley
- Android_Handler实现异步回调加载数据
- Android:仿微博Listview与多线程功能(JSON、数据下载、图片加载、Listview、异步任务)
- android开发教程之handler异步更新ui
- android 异步方式实现数据加载