高效的显示位图(五):管理位图内…

2024-05-03 00:38
文章标签 高效 显示 管理 位图

本文主要是介绍高效的显示位图(五):管理位图内…,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

- 除了缓冲机制,还有其它措施可以用来为垃圾回收和位图重用增加便利
- 针对不同版本:
  • Android 2.2及以前版本,当垃圾回收启动,应用中的线程全部停止,这导致性能损失,Android 2.3.3引入并发垃圾回收机制
  • Android 2.3.3及更早版本,像素数据存储在本地内存,与为图对象(存储于虚拟机堆)本身隔离。本地内存数据无法以可以预知的方式释放,致使程序可能超过内存限制而崩溃。Android 3.0以后,像素数据也存储于虚拟机堆
- 本篇展示如何根据不同版本优化位图内存管理

Android 2.3.3以下版本内存管理
- recycle()方法:允许应用尽快回收内存
private int mCacheRefCount = 0;
private int mDisplayRefCount = 0;
...
// Notify the drawable that the displayed state has changed.
// Keep a count to determine when the drawable is no longer displayed.
public void setIsDisplayed(boolean isDisplayed) {
 
synchronized (this) {
     
if (isDisplayed) {
          mDisplayRefCount
++;
          mHasBeenDisplayed
= true;
     
} else {
          mDisplayRefCount
--;
     
}
 
}
 
// Check to see if recycle() can be called.
  checkState
();
}

// Notify the drawable that the cache state has changed.
// Keep a count to determine when the drawable is no longer being cached.
public void setIsCached(boolean isCached) {
 
synchronized (this) {
     
if (isCached) {
          mCacheRefCount
++;
     
} else {
          mCacheRefCount
--;
     
}
 
}
 
// Check to see if recycle() can be called.
  checkState
();
}

private synchronized void checkState() {
 
// If the drawable cache and display ref counts = 0, and this drawable
 
// has been displayed, then recycle.
 
if (mCacheRefCount <= 0 && mDisplayRefCount <= 0 && mHasBeenDisplayed
         
&& hasValidBitmap()) {
      getBitmap
().recycle();
 
}
}

private synchronized boolean hasValidBitmap() {
 
Bitmap bitmap = getBitmap();
 
return bitmap != null && !bitmap.isRecycled();
}

Android 3.0以上版本内存管理
- BitmapFactory.Options.inBitmap:解码器将尝试重用已经存在的位图对象:
  • 被重用的位图对象必须与源内容大小一致,并且是JPG或PNG格式
  • 被重用的位图的configuration将覆盖inPreferredConfig设置,如果有的话
  • 你应该使用解码方法返回的位图对象。被重用的位图不一定还能用
* 保存一个位图待用:
- 如何保存一个已经存在的位图
HashSet<SoftReference<Bitmap>> mReusableBitmaps;
private LruCache<String, BitmapDrawable> mMemoryCache;

// If you're running on Honeycomb or newer, create
// a HashSet of references to reusable bitmaps.
if (Utils.hasHoneycomb()) {
  mReusableBitmaps
= new HashSet<SoftReference<Bitmap>>();
}

mMemoryCache
= new LruCache<String, BitmapDrawable>(mCacheParams.memCacheSize) {

 
// Notify the removed entry that is no longer being cached.
 
@Override
 
protected void entryRemoved(boolean evicted, String key,
         
BitmapDrawable oldValue, BitmapDrawable newValue) {
     
if (RecyclingBitmapDrawable.class.isInstance(oldValue)) {
         
// The removed entry is a recycling drawable, so notify it
         
// that it has been removed from the memory cache.
         
((RecyclingBitmapDrawable) oldValue).setIsCached(false);
     
} else {
         
// The removed entry is a standard BitmapDrawable.
         
if (Utils.hasHoneycomb()) {
             
// We're running on Honeycomb or later, so add the bitmap
             
// to a SoftReference set for possible use with inBitmap later.
              mReusableBitmaps
.add
                     
(new SoftReference<Bitmap>(oldValue.getBitmap()));
         
}
     
}
 
}
....
}

* 使用现有的位图:
- 解码方法检查是否有现存的位图可用:
public static Bitmap decodeSampledBitmapFromFile(String filename,
     
int reqWidth, int reqHeight, ImageCache cache) {

 
final BitmapFactory.Options options = new BitmapFactory.Options();
 
...
 
BitmapFactory.decodeFile(filename, options);
 
...

 
// If we're running on Honeycomb or newer, try to use inBitmap.
 
if (Utils.hasHoneycomb()) {
      addInBitmapOptions
(options, cache);
 
}
 
...
 
return BitmapFactory.decodeFile(filename, options);
}
- addInBitmapOptions():
private static void addInBitmapOptions(BitmapFactory.Options options,
     
ImageCache cache) {
 
// inBitmap only works with mutable bitmaps, so force the decoder to
 
// return mutable bitmaps.
  options
.inMutable = true;

 
if (cache != null) {
     
// Try to find a bitmap to use for inBitmap.
     
Bitmap inBitmap = cache.getBitmapFromReusableSet(options);

     
if (inBitmap != null) {
         
// If a suitable bitmap has been found, set it as the value of
         
// inBitmap.
          options
.inBitmap = inBitmap;
     
}
 
}
}

// This method iterates through the reusable bitmaps, looking for one
// to use for inBitmap:
protected Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) {
     
Bitmap bitmap = null;

 
if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) {
     
final Iterator<SoftReference<Bitmap>> iterator
             
= mReusableBitmaps.iterator();
     
Bitmap item;

     
while (iterator.hasNext()) {
          item
= iterator.next().get();

         
if (null != item && item.isMutable()) {
             
// Check to see it the item can be used for inBitmap.
             
if (canUseForInBitmap(item, options)) {
                  bitmap
= item;

                 
// Remove from reusable set so it can't be used again.
                  iterator
.remove();
                 
break;
             
}
         
} else {
             
// Remove from the set if the reference has been cleared.
              iterator
.remove();
         
}
     
}
 
}
 
return bitmap;
}
- 最后,此方法检查找到的位图对象是否可用:
private static boolean canUseForInBitmap(
     
Bitmap candidate, BitmapFactory.Options targetOptions) {
 
int width = targetOptions.outWidth / targetOptions.inSampleSize;
 
int height = targetOptions.outHeight / targetOptions.inSampleSize;

 
// Returns true if "candidate" can be used for inBitmap re-use with
 
// "targetOptions".
 
return candidate.getWidth() == width && candidate.getHeight() == height;
}

这篇关于高效的显示位图(五):管理位图内…的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955476

相关文章

Python实现高效地读写大型文件

《Python实现高效地读写大型文件》Python如何读写的是大型文件,有没有什么方法来提高效率呢,这篇文章就来和大家聊聊如何在Python中高效地读写大型文件,需要的可以了解下... 目录一、逐行读取大型文件二、分块读取大型文件三、使用 mmap 模块进行内存映射文件操作(适用于大文件)四、使用 pand

高效管理你的Linux系统: Debian操作系统常用命令指南

《高效管理你的Linux系统:Debian操作系统常用命令指南》在Debian操作系统中,了解和掌握常用命令对于提高工作效率和系统管理至关重要,本文将详细介绍Debian的常用命令,帮助读者更好地使... Debian是一个流行的linux发行版,它以其稳定性、强大的软件包管理和丰富的社区资源而闻名。在使用

SpringBoot使用minio进行文件管理的流程步骤

《SpringBoot使用minio进行文件管理的流程步骤》MinIO是一个高性能的对象存储系统,兼容AmazonS3API,该软件设计用于处理非结构化数据,如图片、视频、日志文件以及备份数据等,本文... 目录一、拉取minio镜像二、创建配置文件和上传文件的目录三、启动容器四、浏览器登录 minio五、

电脑显示hdmi无信号怎么办? 电脑显示器无信号的终极解决指南

《电脑显示hdmi无信号怎么办?电脑显示器无信号的终极解决指南》HDMI无信号的问题却让人头疼不已,遇到这种情况该怎么办?针对这种情况,我们可以采取一系列步骤来逐一排查并解决问题,以下是详细的方法... 无论你是试图为笔记本电脑设置多个显示器还是使用外部显示器,都可能会弹出“无HDMI信号”错误。此消息可能

IDEA中的Kafka管理神器详解

《IDEA中的Kafka管理神器详解》这款基于IDEA插件实现的Kafka管理工具,能够在本地IDE环境中直接运行,简化了设置流程,为开发者提供了更加紧密集成、高效且直观的Kafka操作体验... 目录免安装:IDEA中的Kafka管理神器!简介安装必要的插件创建 Kafka 连接第一步:创建连接第二步:选

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只