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. Matalab之模糊KMeans原理

    对Kmeans方法相信大家都会不陌生,这是一种广泛被应用的基于划分的聚类算法.首先对它的核心思想做一个简单的介绍: 算法把n个向量xj(1,2…,n)分为c个组Gi(i=1,2,…,c),并求每组的聚 ...

  2. 【POJ】3468 A Simple Problem with Integers ——线段树 成段更新 懒惰标记

    A Simple Problem with Integers Time Limit:5000MS   Memory Limit:131072K Case Time Limit:2000MS Descr ...

  3. Linux,Unix各种版本的操作系统在线安装软件命令

    摘自:http://blog.csdn.net/zjg555543/article/details/8278266 linux和unix,各个版本的操作系统都有自己的软件安装方式,最方便的莫过于在线安 ...

  4. UVALive 6665 Dragonas Cruller

    题目链接:https://icpcarchive.ecs.baylor.edu/external/66/6665.pdf 题目大意: 有一个3 * 3 的格子: 每个格子上面的数字能够朝上下左右四个方 ...

  5. android开发 不注意的异常

    近期刚上班,做了一个应用,要上线.測试天天測试,天天有bug,个人总结了几个常常忽略的地方: 1:在 继承 BaseAdapter 的 @Override public int getCount() ...

  6. java PriorityBlockingQueue 基于优先级队列,的读出操作可以阻止.

    java PriorityBlockingQueue 基于优先级队列.的读出操作可以阻止. package org.rui.thread.newc; import java.util.ArrayLis ...

  7. codeblocks 使用指南z

    1.界面风格更改 首先贴怎么普通设置出来,或者改配置文件 这是我的风格 类似于DEV-CPP里面的一个主题,看的很舒服 具体设置如下: Settings-Editor 1.代码当前行高亮 在Gener ...

  8. java 判断字符串编码

    String iso8859 = new String(sb.toString().getBytes("iso8859-1"));String gbk = new String(s ...

  9. spring boot 中文文档

    https://qbgbook.gitbooks.io/spring-boot-reference-guide-zh/content/VII.%20Spring%20Boot%20CLI/index. ...

  10. timeout Timeout时间已到.在操作完成之前超时时间已过或服务器未响应

    Timeout时间已到.在操作完成之前超时时间已过或服务器未响应 问题 在使用asp.net开发的应用程序查询数据的时候,遇到页面请求时间过长且返回"Timeout时间已到.在操作完成之间超 ...