android 的线程模型:当一个 android 的应用运行后,就会有一个 UI 的 main 线程启动 , 这是一个非常重要的线程,它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与 android 控件 交互的线程。比如,当你在屏幕上的 EditText 上输入文字, UI 线程会把这个事件分发给刚输入文字的 EditText ,紧接会向事件队列发送一个更新 ( invalidate )请求。 UI 线程会把这个请求移出事件队列并通知 EditText 在屏幕上重新绘制自身。

这种单线线程模型就会使得 android 的应用程序性能低下, 如果在这个单线程里执行一些耗时的操作, 比如访问数据库, 或是从网络端下载图片, 就会会阻塞整个用户界面。 比如如下操作:

Bitmap b =  loadImageFromNetwork();  

这个操作非常耗时, 在这种情况下你会发现 , 界面僵死在那里并且 android 在系统 5 秒中后没有反应,会显示一个关闭或等待的错误。

也许我们可以使用一个新的 Thread 来解决它

new Thread(new Runnable() {
public void run() {
Bitmap b = loadImageFromNetwork();
mImageView.setImageBitmap( b );
}
}).start();

但这样会发生一些很难察觉的错误, 因为我们知道 UI 线程不是线程安全的。当然有很多种方法来处理这个问题:

android 提供了几种在其他线程中访问 UI 线程的方法。

• Activity.runOnUiThread( Runnable )
• View.post( Runnable )
• View.postDelayed( Runnable, long )
• Hanlder

new Thread( new Runnable() {
public void run() {
final Bitmap b = loadImageFromNetwork();
mImageView.post( new Runnable() {
mImageView.setImageBitmap( b );
});
}
}).start();

这种方法比较繁琐,同时当你需要实现一些很复杂的操作并需要频繁地更新UI 时这会变得更糟糕。为了解决这个问题,android 提供了一个工具类:AsyncTask ,它使创建需要与用户界面交互的长时间运行的任务变得更简单。

就拿加载网络图片举个例子:

ublic class CanvasImageTask extends AsyncTask<ImageView, Void, Bitmap>{
private ImageView gView ; protected Bitmap doInBackground(ImageView... views) {
Bitmap bmp = null ;
ImageView view = views[0];
// 根据iconUrl获取图片并渲染,iconUrl的url放在了view的tag中。
if (view.getTag() != null) {
try {
URL url = new URL(view.getTag().toString());
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream stream = conn.getInputStream();
bmp = BitmapFactory.decodeStream(stream);
stream.close();
} catch (Exception e) {
Log.v("img", e.getMessage());
return null;
}
}
this.gView = view;
return bmp;
}
protected void onPostExecute(Bitmap bm) {
if (bm != null) {
this.gView.setImageBitmap(bm);
this.gView = null ;
}
} }
在Activity中直接调用
if(!img.isDrawingCacheEnabled() || !holder.image.getTag().equals(imgpath)){
img.setImageResource(R.drawable.icon_app);
img.setTag(imgpath);
try{
new CanvasImageTask().execute(img);
img.setDrawingCacheEnabled(true);
}catch (Exception e) {
Log.e("error", "RejectedExecutionException in content_img: " + imgpath);

这样图片加载使用异步线程便不会进行堵塞发生错误,我们还可以使用 callback 在图片加载完后进行回调

public class CanvasImageTaskCall extends AsyncTask<ImageView, Void, Bitmap> implements Callback{
private ImageView gView ; protected Bitmap doInBackground(ImageView... views) {
Bitmap bmp = null ;
ImageView view = views[0];
// 根据iconUrl获取图片并渲染,iconUrl的url放在了view的tag中。
if (view.getTag() != null) {
try {
URL url = new URL(view.getTag().toString());
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream stream = conn.getInputStream();
bmp = BitmapFactory.decodeStream(stream);
stream.close();
} catch (Exception e) {
e.printStackTrace();
Log.v("img", e.getMessage());
Message msg = new Message();
msg.what = 0;
handleMessage(msg);
return null;
}
}
this.gView = view;
return bmp;
}
protected void onPostExecute(Bitmap bm) {
if (bm != null) {
this.gView.setImageBitmap(bm);
this.gView.setTag(bm);
this.gView = null ;
Message msg = new Message();
msg.what = 1;
handleMessage(msg);
}
}
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
return false;
} }

在 Activity 中直接调用

new CanvasImageTaskCall(){
@Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case 0:
Log.i("test", "图片加载失败");
break;
case 1:
Log.i("test", "图片加载成功");
break;
default:
break;
}
saveButton.setTextColor(Color.WHITE);
saveButton.setClickable(true);
bitmap = (Bitmap) imageView.getTag();
return super.handleMessage(msg);
}
}.execute(img);

android 的线程模型和AsyncTask的更多相关文章

  1. Android中消息系统模型和Handler Looper

    http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html Android中消息系统模型和Handler Looper 作为Andro ...

  2. Android线程管理之AsyncTask异步任务

    前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 线程管理相 ...

  3. Android(java)学习笔记149:Android线程形态之 AsyncTask (异步任务)

    1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点        AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...

  4. Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析

    本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8515304.html 一.AsyncTask的使用 AsyncTask是一种轻 ...

  5. Android(java)学习笔记92:Android线程形态之 AsyncTask (异步任务)

    1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点        AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...

  6. 黑马-----内存模型和volatile详解

    黑马程序员:Java培训.Android培训.iOS培训..Net培训 JAVA线程-内存模型和volatile详解 一.单核内存模型 1.程序运行时,将临时数据存放到Cache中 2.将CPU计算所 ...

  7. Android Studio利用异步任务AsyncTask发送post请求获取json数据

    syncTask,是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主 ...

  8. android操作线程各种方法解析

    (一)刚开始学习android的时候我是这么写的 new Thread( new Runnable() { public void run() { myView.invalidate(); } }). ...

  9. Android UI线程和非UI线程

    Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...

随机推荐

  1. webview相关链接

    http://tech.it168.com/a2011/0517/1191/000001191561_2.shtml http://www.eoeandroid.com/thread-272495-1 ...

  2. thinkphp中的where()方法

    where方法的用法是ThinkPHP查询语言的精髓,也是ThinkPHP ORM的重要组成部分和亮点所在,可以完成包括普通查询.表达式查询.快捷查询.区间查询.组合查询在内的查询操作.where方法 ...

  3. bzoj3293 [Cqoi2011]分金币&&bzoj1045 [HAOI2008]糖果传递

    Description 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. Inpu ...

  4. linux之SQL语句简明教程---BETWEEN

    IN 这个指令可以让我们依照一或数个不连续 (discrete) 的值的限制之内抓出数据库中的值,而BETWEEN 则是让我们可以运用一个范围 (range) 内抓出数据库中的值.BETWEEN 这个 ...

  5. Android解析中国天气网的Json数据

    在Android开发中.一般的APP都是通过获取server端的数据来更新UI.从server获取到的数据能够是Json.它的数据量要比XML要小,这里解析中国天气网上获取的数据,尽管已经不再更新了. ...

  6. jQuery下实现检测指定元素加载完毕

    检测元素出现方法.虽然是基于 jQuery 的,但是代码很简洁,可以修改成纯js版的. 文本 jQuery.fn.wait = function (func, times, interval) { v ...

  7. 查看oracle锁及解决办法

    SQL> select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1, v$session t2 whe ...

  8. HTML5新特性学习-1

    本文在于巩固基础 新特性:音频的使用 <!DOCTYPE html> <html> <head lang="en"> <meta char ...

  9. XSD (xml Schema Definition)

    .xsd文件是定义DataSet的XML文件,利用XML文件的结构优势容易可视化地设计DataSet,设计完它会生成相应的.cs文件,里面的内容就是对应的类型化的DataSet.你的代码里的DataA ...

  10. 03JS高级关于为空的变量判断

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...