最近研究nullnull,稍微总结一下,以后继续补充:

The BitmapFactory.decode* methods, should not be executed on the main UI thread if the source data is read from disk or a network location (or really any source other than memory). The time this data takes to load is unpredictable and depends on a variety of factors (speed of reading from disk or network, size of image, power of CPU, etc.). If one of these tasks blocks the UI thread, the system flags your application as non-responsive and the user has the option of closing it (seeDesigning for Responsiveness for more information). http://blog.csdn.net/sergeycao

This lesson walks you through processing bitmaps in a background thread using AsyncTask and shows you how to handle concurrency issues.

Use an AsyncTask

The AsyncTask class provides an easy way to execute some work in a background thread and publish the results back on the UI thread. To use it, create a subclass and override the provided methods. Here’s an example of loading a large image into an ImageView using AsyncTask anddecodeSampledBitmapFromResource():

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {private final WeakReference<ImageView> imageViewReference;private int data = 0;public BitmapWorkerTask(ImageView imageView) {// Use a WeakReference to ensure the ImageView can be garbage collectedimageViewReference = new WeakReference<ImageView>(imageView);}// Decode image in background.@Overrideprotected Bitmap doInBackground(Integer... params) {data = params[0];return decodeSampledBitmapFromResource(getResources(), data, 100, 100));}// Once complete, see if ImageView is still around and set bitmap.@Overrideprotected void onPostExecute(Bitmap bitmap) {if (imageViewReference != null && bitmap != null) {final ImageView imageView = imageViewReference.get();if (imageView != null) {imageView.setImageBitmap(bitmap);}}}
}

The WeakReference to the ImageView ensures that theAsyncTask does not prevent the ImageView and anything it references from being garbage collected. There’s no guarantee theImageView is still around when the task finishes, so you must also check the reference inonPostExecute(). The ImageView may no longer exist, if for example, the user navigates away from the activity or if a configuration change happens before the task finishes.

To start loading the bitmap asynchronously, simply create a new task and execute it:

public void loadBitmap(int resId, ImageView imageView) {BitmapWorkerTask task = new BitmapWorkerTask(imageView);task.execute(resId);
}

Handle Concurrency

Common view components such as ListView and GridView introduce another issue when used in conjunction with theAsyncTask as demonstrated in the previous section. In order to be efficient with memory, these components recycle child views as the user scrolls. If each child view triggers anAsyncTask, there is no guarantee that when it completes, the associated view has not already been recycled for use in another child view. Furthermore, there is no guarantee that the order in which asynchronous tasks are started is the order that they complete.

The blog post Multithreading for Performance further discusses dealing with concurrency, and offers a solution where theImageView stores a reference to the most recent AsyncTask which can later be checked when the task completes. Using a similar method, theAsyncTask from the previous section can be extended to follow a similar pattern.

每日一道理
自己把自己说服了,是一种理智的胜利;自己被自己感动了,是一种心灵的升华;自己把自己征服了,是一种人生的成功。

Create a dedicated Drawable subclass to store a reference back to the worker task. In this case, aBitmapDrawable is used so that a placeholder image can be displayed in theImageView while the task completes:

static class AsyncDrawable extends BitmapDrawable {private final WeakReference<BitmapWorkerTask> bitmapWorkerTaskReference;public AsyncDrawable(Resources res, Bitmap bitmap,BitmapWorkerTask bitmapWorkerTask) {super(res, bitmap);bitmapWorkerTaskReference =new WeakReference<BitmapWorkerTask>(bitmapWorkerTask);}public BitmapWorkerTask getBitmapWorkerTask() {return bitmapWorkerTaskReference.get();}
}

Before executing the BitmapWorkerTask, you create anAsyncDrawable and bind it to the target ImageView:

public void loadBitmap(int resId, ImageView imageView) {if (cancelPotentialWork(resId, imageView)) {final BitmapWorkerTask task = new BitmapWorkerTask(imageView);final AsyncDrawable asyncDrawable =new AsyncDrawable(getResources(), mPlaceHolderBitmap, task);imageView.setImageDrawable(asyncDrawable);task.execute(resId);}
}

The cancelPotentialWork method referenced in the code sample above checks if another running task is already associated with theImageView. If so, it attempts to cancel the previous task by callingcancel(). In a small number of cases, the new task data matches the existing task and nothing further needs to happen. Here is the implementation ofcancelPotentialWork:

public static boolean cancelPotentialWork(int data, ImageView imageView) {final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);if (bitmapWorkerTask != null) {final int bitmapData = bitmapWorkerTask.data;if (bitmapData != data) {// Cancel previous taskbitmapWorkerTask.cancel(true);} else {// The same work is already in progressreturn false;}}// No task associated with the ImageView, or an existing task was cancelledreturn true;
}

A helper method, getBitmapWorkerTask(), is used above to retrieve the task associated with a particularImageView:

private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {if (imageView != null) {final Drawable drawable = imageView.getDrawable();if (drawable instanceof AsyncDrawable) {final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;return asyncDrawable.getBitmapWorkerTask();}}return null;
}

The last step is updating onPostExecute() in BitmapWorkerTask so that it checks if the task is cancelled and if the current task matches the one associated with theImageView:

class BitmapWorkerTask extends AsyncTask<Integer, Void, Bitmap> {...@Overrideprotected void onPostExecute(Bitmap bitmap) {

if (isCancelled()) { bitmap = null; }

if (imageViewReference != null && bitmap != null) { final ImageView imageView = imageViewReference.get();

final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView);

if (

this == bitmapWorkerTask &&

imageView != null) { imageView.setImageBitmap(bitmap); } } } }

This implementation is now suitable for use in ListView andGridView components as well as any other components that recycle their child views. Simply callloadBitmap where you normally set an image to your ImageView. For example, in aGridView implementation this would be in the getView() method of the backing adapter.

文章结束给大家分享下程序员的一些笑话语录: 很多所谓的牛人也不过如此,离开了你,微软还是微软,Google还是Google,苹果还是苹果,暴雪还是暴雪,而这些牛人离开了公司,自己什么都不是。

nullnullProcessing Bitmaps Off the UI Thread 处理来自UI线程的位图相关推荐

  1. 第四十四课:jQuery UI和jQuery easy UI

    jQuery UI是jQuery官方提供的功能效果和UI样式.作为官方出的东西,它一直没有被人们看重,一是它没有datagrid,tree等UI库必备的东西,二是它修改太过频繁,体积庞大.其实它所有以 ...

  2. Android,UI主线程与子线程

    在一个Android 程序开始运行的时候,会单独启动一个Process.默认的情况下,所有这个程序中的Activity或者Service(Service和 Activity只是Android提供的Co ...

  3. android ui ue,什么是UI设计,UE设计,二者有什么区别?

    原标题:什么是UI设计,UE设计,二者有什么区别? 你是不是常常在生活中听到这些名词呢?在网路盛行的互联网时代,也因而产生了各种新兴职业,UI/UE 设计师便是现在当红的职业选择,虽然在国外已发展多年 ...

  4. 零基础小白怎么自学UI设计?自学UI设计有什么方法?

    本文由:"学设计上兔课网"原创,图片素材来自网络,仅供学习分享 零基础小白怎么自学UI设计?自学UI设计有什么方法?学ui设计,相信大家的第一选择就是想着自学.毕竟报班的费用不便宜 ...

  5. .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调、APM、EAP、TPL、aysnc、await

    windows系统是一个多线程的操作系统.一个程序至少有一个进程,一个进程至少有一个线程.进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线 ...

  6. 新人零基础怎么学UI设计?学UI设计要掌握哪些软件?

    本文由:"学设计上兔课网"原创,图片素材来自网络,仅供学习分享 新人零基础怎么学UI设计?学UI设计要掌握哪些软件?现如今,UI设计师的出现,是互联网时代的设计变革带来的.越来越多 ...

  7. UI培训分享:UI设计行业常见术语有哪些?

    学会UI设计之后,大家后面就要进入到真正的UI设计行业了,那么关于UI设计行业的常见术语大家也要做一些了解,尤其是新人,这对后面的工作会很多有帮助,本期UI培训教程就给大家介绍一下UI设计行业常见术语 ...

  8. UI培训分享:UI设计师要掌握哪些知识点

    UI设计师除了要学会自己所在行业的技术之外,还要了解一些其他的知识点,这些知识点都会在今后的工作中带来帮助,甚至是加分项,那么下面来看看小编为大家介绍的UI培训分享:UI设计师要掌握哪些知识点? UI ...

  9. UI设计培训:UI构思创意技巧和方法

    想要作为一名合格的UI设计师,那么创意技巧和方法是非常重要的,很多刚入职场的新人或者是工作多年的设计师都会在创意技巧和方法上遇到瓶颈,下面小编为大家整理一些UI构思创意技巧和方法,希望能够帮助到大家. ...

最新文章

  1. 为什么结构主机和全局编录服务器不能放在同一个域控制器上?
  2. iOS 11开发教程(十六)iOS11应用视图之删除空白视图
  3. [leetcode] 数字游戏
  4. Zygote进程启动流程分析
  5. 这是我的第一个python程序怎么打-我的第一个Python程序(运行)
  6. 整理大型网站架构必知必会的几个服务器知识
  7. 洛谷精选 - 字符串合集
  8. 卡萨帝:用发明去超越历史!15年走完百年路
  9. Java程序员需要掌握的计算机底层知识(一):CPU基本组成、指令乱序执行、合并写技术、非同一访问内存 NUMA
  10. [Swagger2]SpringBoot集成Swagger
  11. 契约测试:解决微服务测试的问题
  12. mysql操作库命令_MYSQL数据库------操作命令笔记
  13. Python天气预报查询
  14. Session 的几种存储方式及优缺点
  15. 深度学习框架PyTorch:入门与实践 学习(一)
  16. 基于机器学习的回归拟合、详细总结
  17. 1024X600RGB屏幕规格书分析
  18. shutil,re,hashlib,subprocess模块及其相关
  19. 【诗歌】值得背诵古诗(一)
  20. H5页面input输入框,在ios手机中被顶出页面解决方案

热门文章

  1. x61 linux 驱动 无线网卡,Linux环境Thinkpad X61 4G内存Mtrr表错误
  2. word2vec模型评估_NLP之文本分类:「Tf-Idf、Word2Vec和BERT」三种模型比较
  3. jdbctemplate 执行多条sql_白帽推荐:可以自动检索、挖掘sql注入的神器,sqlmap入门实战
  4. js双通信java,js和java的http通信
  5. Spring bean作用范围
  6. 16 The Terminal and Job Control
  7. TensorFlow losses
  8. 字节(bytes) 二进制序列类型
  9. javasript ide
  10. Pandas Index 更新和计算(Modifyingcomputations)