android 的线程模型和AsyncTask
这种单线线程模型就会使得 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的更多相关文章
- Android中消息系统模型和Handler Looper
http://www.cnblogs.com/bastard/archive/2012/06/08/2541944.html Android中消息系统模型和Handler Looper 作为Andro ...
- Android线程管理之AsyncTask异步任务
前言: 前面几篇文章主要学习了线程以及线程池的创建与使用,今天来学习一下AsyncTask异步任务,学习下AsyncTask到底解决了什么问题?然而它有什么弊端?正所谓知己知彼百战百胜嘛! 线程管理相 ...
- Android(java)学习笔记149:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- Android查缺补漏(线程篇)-- AsyncTask的使用及原理详细分析
本文作者:CodingBlock 文章链接:http://www.cnblogs.com/codingblock/p/8515304.html 一.AsyncTask的使用 AsyncTask是一种轻 ...
- Android(java)学习笔记92:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- 黑马-----内存模型和volatile详解
黑马程序员:Java培训.Android培训.iOS培训..Net培训 JAVA线程-内存模型和volatile详解 一.单核内存模型 1.程序运行时,将临时数据存放到Cache中 2.将CPU计算所 ...
- Android Studio利用异步任务AsyncTask发送post请求获取json数据
syncTask,是Android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步执行的程度(可以通过接口实现UI进度更新),最后反馈执行的结果给UI主 ...
- android操作线程各种方法解析
(一)刚开始学习android的时候我是这么写的 new Thread( new Runnable() { public void run() { myView.invalidate(); } }). ...
- Android UI线程和非UI线程
Android UI线程和非UI线程 UI线程及Android的单线程模型原则 当应用启动,系统会创建一个主线程(main thread). 这个主线程负责向UI组件分发事件(包括绘制事件),也是在这 ...
随机推荐
- webview相关链接
http://tech.it168.com/a2011/0517/1191/000001191561_2.shtml http://www.eoeandroid.com/thread-272495-1 ...
- thinkphp中的where()方法
where方法的用法是ThinkPHP查询语言的精髓,也是ThinkPHP ORM的重要组成部分和亮点所在,可以完成包括普通查询.表达式查询.快捷查询.区间查询.组合查询在内的查询操作.where方法 ...
- bzoj3293 [Cqoi2011]分金币&&bzoj1045 [HAOI2008]糖果传递
Description 圆桌上坐着n个人,每人有一定数量的金币,金币总数能被n整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值. Inpu ...
- linux之SQL语句简明教程---BETWEEN
IN 这个指令可以让我们依照一或数个不连续 (discrete) 的值的限制之内抓出数据库中的值,而BETWEEN 则是让我们可以运用一个范围 (range) 内抓出数据库中的值.BETWEEN 这个 ...
- Android解析中国天气网的Json数据
在Android开发中.一般的APP都是通过获取server端的数据来更新UI.从server获取到的数据能够是Json.它的数据量要比XML要小,这里解析中国天气网上获取的数据,尽管已经不再更新了. ...
- jQuery下实现检测指定元素加载完毕
检测元素出现方法.虽然是基于 jQuery 的,但是代码很简洁,可以修改成纯js版的. 文本 jQuery.fn.wait = function (func, times, interval) { v ...
- 查看oracle锁及解决办法
SQL> select t2.username,t2.sid,t2.serial#,t2.logon_time from v$locked_object t1, v$session t2 whe ...
- HTML5新特性学习-1
本文在于巩固基础 新特性:音频的使用 <!DOCTYPE html> <html> <head lang="en"> <meta char ...
- XSD (xml Schema Definition)
.xsd文件是定义DataSet的XML文件,利用XML文件的结构优势容易可视化地设计DataSet,设计完它会生成相应的.cs文件,里面的内容就是对应的类型化的DataSet.你的代码里的DataA ...
- 03JS高级关于为空的变量判断
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...