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

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构建一个高效词汇表》在自然语言处理(NLP)领域,构建高效的词汇表是文本预处理的关键步骤,本文将解析一个使用Python实现的n-gram词频统计工具,感兴趣的可以了解下... 目录一、项目背景与目标1.1 技术需求1.2 核心技术栈二、核心代码解析2.1 数据处理函数2.2 数据处理流程

RedisTemplate默认序列化方式显示中文乱码的解决

《RedisTemplate默认序列化方式显示中文乱码的解决》本文主要介绍了SpringDataRedis默认使用JdkSerializationRedisSerializer导致数据乱码,文中通过示... 目录1. 问题原因2. 解决方案3. 配置类示例4. 配置说明5. 使用示例6. 验证存储结果7.

Python中bisect_left 函数实现高效插入与有序列表管理

《Python中bisect_left函数实现高效插入与有序列表管理》Python的bisect_left函数通过二分查找高效定位有序列表插入位置,与bisect_right的区别在于处理重复元素时... 目录一、bisect_left 基本介绍1.1 函数定义1.2 核心功能二、bisect_left 与

Spring中管理bean对象的方式(专业级说明)

《Spring中管理bean对象的方式(专业级说明)》在Spring框架中,Bean的管理是核心功能,主要通过IoC(控制反转)容器实现,下面给大家介绍Spring中管理bean对象的方式,感兴趣的朋... 目录1.Bean的声明与注册1.1 基于XML配置1.2 基于注解(主流方式)1.3 基于Java

基于Python+PyQt5打造一个跨平台Emoji表情管理神器

《基于Python+PyQt5打造一个跨平台Emoji表情管理神器》在当今数字化社交时代,Emoji已成为全球通用的视觉语言,本文主要为大家详细介绍了如何使用Python和PyQt5开发一个功能全面的... 目录概述功能特性1. 全量Emoji集合2. 智能搜索系统3. 高效交互设计4. 现代化UI展示效果

Python使用FFmpeg实现高效音频格式转换工具

《Python使用FFmpeg实现高效音频格式转换工具》在数字音频处理领域,音频格式转换是一项基础但至关重要的功能,本文主要为大家介绍了Python如何使用FFmpeg实现强大功能的图形化音频转换工具... 目录概述功能详解软件效果展示主界面布局转换过程截图完成提示开发步骤详解1. 环境准备2. 项目功能结

Mysql中的用户管理实践

《Mysql中的用户管理实践》:本文主要介绍Mysql中的用户管理实践,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录13. 用户管理13.1 用户 13.1.1 用户信息 13.1.2 创建用户 13.1.3 删除用户 13.1.4 修改用户

idea中project的显示问题及解决

《idea中project的显示问题及解决》:本文主要介绍idea中project的显示问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录idea中project的显示问题清除配置重China编程新生成配置总结idea中project的显示问题新建空的pr

Python Pandas高效处理Excel数据完整指南

《PythonPandas高效处理Excel数据完整指南》在数据驱动的时代,Excel仍是大量企业存储核心数据的工具,Python的Pandas库凭借其向量化计算、内存优化和丰富的数据处理接口,成为... 目录一、环境搭建与数据读取1.1 基础环境配置1.2 数据高效载入技巧二、数据清洗核心战术2.1 缺失

linux服务之NIS账户管理服务方式

《linux服务之NIS账户管理服务方式》:本文主要介绍linux服务之NIS账户管理服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、所需要的软件二、服务器配置1、安装 NIS 服务2、设定 NIS 的域名 (NIS domain name)3、修改主