博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android线程模型和AsyncTask
阅读量:6113 次
发布时间:2019-06-21

本文共 5564 字,大约阅读时间需要 18 分钟。

hot3.png

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

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

Bitmap b =  loadImageFromNetwork();

EE

这个操作非常耗时, 在这种情况下你会发现 , 界面僵死在那里并且 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
{ 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
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);

转载于:https://my.oschina.net/u/559701/blog/87455

你可能感兴趣的文章
uva 10806
查看>>
纯CSS3绘制的黑色图标按钮组合
查看>>
Linux中环境变量文件及配置
查看>>
从0开始学Flutter
查看>>
mysql操作入门基础之对数据库和表的增删改查
查看>>
IIS负载均衡
查看>>
分布式事务,EventBus 解决方案:CAP【中文文档】
查看>>
Linux下的CPU性能瓶颈分析案例
查看>>
spring mvc入门
查看>>
2012在数据库技术会议上的讲话PPT打包
查看>>
【Android】 TextView设置个别字体样式
查看>>
python svn
查看>>
raise语句
查看>>
sequence2(高精度dp)
查看>>
如何向 Linux 内核上游提交 Patch ?
查看>>
Go编程笔记(7)
查看>>
Go语言int类型绑定方法
查看>>
pid控制的文章
查看>>
MySQL中EXPLAIN命令详解
查看>>
redis 单点部署
查看>>