使用LruCache为GridView加载大量sdcard的图片

最近做android开发的时候遇到读取sdcard下面图片展示,在网上找了很多相关资料,最终得于解决。在这里首先感谢下互联网的朋友们。接下来我把我实现的代码贴出来和大家分享下。由于代码里面的注释写的很清楚。我就不再一一描述了。

package com.zhuyesoft.sgzs.ui;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.ArrayAdapter;
import android.widget.GridView;
import android.widget.ImageView;

import com.zhuyesoft.sgzs.activity.R;
/**
 * LruCache的流程分析: 我们从第一次进入应用的情况下开始 1 依据图片的Url从LruCache缓存中取图片.
 * 若图片存在缓存中,则显示该图片;否则显示默认图片 2 因为是第一次进入该界面所以会执行: loadBitmaps(firstVisibleItem,
 * visibleItemCount); 我们从loadBitmaps()方法作为切入点,继续往下梳理 3
 * 尝试从LruCache缓存中取图片.如果在显示即可,否则进入4 4 开启一个异步任务下载图片.下载完成后显示图片,并且将 该图片存入LruCache缓存中
 * 
 * 在停止滑动时,会调用loadBitmaps(firstVisibleItem, visibleItemCount) 情况与上类似
 */
@SuppressLint("NewApi")
public class GridViewAdapter extends ArrayAdapter<String> {

	private GridView mGridView;
	// 图片缓存类
	private LruCache<String, Bitmap> mLruCache;
	// GridView中可见的第一张图片的下标
	private int mFirstVisibleItem;
	// GridView中可见的图片的数量
	private int mVisibleItemCount;
	// 记录是否是第一次进入该界面
	private boolean isFirstEnterThisActivity = true;
	private  String[]  imageUrls;

	public GridViewAdapter(Context context, int textViewResourceId,
			String[] objects, GridView gridView) {
		super(context, textViewResourceId, objects);

		mGridView = gridView;
		mGridView.setOnScrollListener(new ScrollListenerImpl());
		imageUrls=objects;

		// 获取应用程序最大可用内存
		int maxMemory = (int) Runtime.getRuntime().maxMemory();
		// 设置图片缓存大小为maxMemory的1/6
		int cacheSize = maxMemory / 6;

		mLruCache = new LruCache<String, Bitmap>(cacheSize) {
			@Override
			protected int sizeOf(String key, Bitmap bitmap) {
				return bitmap.getByteCount();
			}
		};

	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		String url = getItem(position);
		View view;
		if (convertView == null) {
			view = LayoutInflater.from(getContext()).inflate(
					R.layout.activity_view_photo_gridview_item, null);
		} else {
			view = convertView;
		}
		ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
		// 为该ImageView设置一个Tag,防止图片错位
		imageView.setTag(url);
		// 为该ImageView设置显示的图片
		setImageForImageView(url, imageView);
		return view;
	}

	/**
	 * 为ImageView设置图片(Image) 1 从缓存中获取图片 2 若图片不在缓存中则为其设置默认图片
	 */
	private void setImageForImageView(String imageUrl, ImageView imageView) {
		Bitmap bitmap = getBitmapFromLruCache(imageUrl);
		if (bitmap != null) {
			imageView.setImageBitmap(bitmap);
		} else {
			imageView.setImageResource(R.drawable.default_image);
		}
	}

	/**
	 * 将图片存储到LruCache
	 */
	public void addBitmapToLruCache(String key, Bitmap bitmap) {
		if (getBitmapFromLruCache(key) == null) {
			mLruCache.put(key, bitmap);
		}
	}

	/**
	 * 从LruCache缓存获取图片
	 */
	public Bitmap getBitmapFromLruCache(String key) {
		return mLruCache.get(key);
	}

	/**
	 * 为GridView的item加载图片
	 * 
	 * @param firstVisibleItem
	 *            GridView中可见的第一张图片的下标
	 * 
	 * @param visibleItemCount
	 *            GridView中可见的图片的数量
	 * 
	 */
	private void loadBitmaps(int firstVisibleItem, int visibleItemCount) {
		try {
			for (int i = firstVisibleItem; i < firstVisibleItem
					+ visibleItemCount; i++) {
				String imageUrl = imageUrls[i];
				Bitmap bitmap = getBitmapFromLruCache(imageUrl);
				if (bitmap == null) {
					bitmap=BitmapFactory.decodeFile(imageUrl);
					ImageView imageView = (ImageView) mGridView.findViewWithTag(imageUrl);
					if (imageView != null && bitmap != null) {
						imageView.setImageBitmap(bitmap);
					}
					//将从SDCard读取的图片添加到LruCache中
					addBitmapToLruCache(imageUrl, bitmap);
				} else {
					// 依据Tag找到对应的ImageView显示图片
					ImageView imageView = (ImageView) mGridView
							.findViewWithTag(imageUrl);
					if (imageView != null && bitmap != null) {
						imageView.setImageBitmap(bitmap);
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	
	private class ScrollListenerImpl implements OnScrollListener {
		/**
		 * 
		 * 我们的本意是通过onScrollStateChanged获知:每次GridView停止滑动时加载图片 但是存在一个特殊情况:
		 * 当第一次入应用的时候,此时并没有滑动屏幕的操作即不会调用onScrollStateChanged,但应该加载图片.
		 * 所以在此处做一个特殊的处理. 即代码: if (isFirstEnterThisActivity && visibleItemCount
		 * > 0) { loadBitmaps(firstVisibleItem, visibleItemCount);
		 * isFirstEnterThisActivity = false; }
		 * 
		 * ------------------------------------------------------------
		 * 
		 * 其余的都是正常情况. 所以我们需要不断保存:firstVisibleItem和visibleItemCount
		 * 从而便于中在onScrollStateChanged()判断当停止滑动时加载图片
		 * 
		 */
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			mFirstVisibleItem = firstVisibleItem;
			mVisibleItemCount = visibleItemCount;
			if (isFirstEnterThisActivity && visibleItemCount > 0) {
				System.out.println("---> 第一次进入该界面");
				loadBitmaps(firstVisibleItem, visibleItemCount);
				isFirstEnterThisActivity = false;
			}
		}

		/**
		 * GridView停止滑动时下载图片 其余情况下取消所有正在下载或者等待下载的任务
		 */
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			if (scrollState == SCROLL_STATE_IDLE) {
				loadBitmaps(mFirstVisibleItem, mVisibleItemCount);
			}
		}

	}
}

 

package cc.testlrucache;

import android.os.Bundle;
import android.widget.GridView;
import android.app.Activity;
/**
 * Demo描述:
 * Android利用LruCache为GridView加载大量本地图片完整示例,防止OOM
 * 
 * 更多参考:
 * http://blog.youkuaiyun.com/lfdfhl
 */
public class MainActivity extends Activity {
	private GridView mGridView;
	private GridViewAdapter mGridViewAdapter;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		init();
	}
	
	private void init(){
		mGridView = (GridView) findViewById(R.id.gridView);
		mGridViewAdapter = new GridViewAdapter(this, 0, ImagesPath.IMAGES_PATH, mGridView);
		mGridView.setAdapter(mGridViewAdapter);
	}

}

 

package cc.testlrucache;

public class ImagesPath {

	public final static String DIR="/mnt/sdcard/Test/";
	public final static String[] IMAGES_PATH = new String[] {
		DIR+"a.jpg",
		DIR+"b.jpg",
		DIR+"c.jpg",
		DIR+"d.jpg",
		DIR+"e.jpg",
		DIR+"f.jpg",
		DIR+"g.jpg",
		DIR+"h.jpg",
		DIR+"i.jpg",
		DIR+"j.jpg",
		DIR+"k.jpg",
		DIR+"l.jpg",
		DIR+"m.jpg",
		DIR+"n.jpg",
		DIR+"o.jpg",
		DIR+"p.jpg",
		DIR+"q.jpg",
		DIR+"r.jpg",
		DIR+"s.jpg",
		DIR+"t.jpg",
		DIR+"w.jpg",
		DIR+"x.jpg",
		DIR+"y.jpg",
		DIR+"z.jpg",
		DIR+"za.jpg",
		DIR+"zb.jpg",
		DIR+"zc.jpg",
		DIR+"zd.jpg",
		DIR+"ze.jpg",
		DIR+"zf.jpg",
		DIR+"zg.jpg",
		DIR+"zh.jpg",
		DIR+"zi.jpg",
		DIR+"zj.jpg",
		DIR+"zk.jpg",
		DIR+"zl.jpg",
		DIR+"zm.jpg"
};
}

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <GridView
        android:id="@+id/gridView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:columnWidth="100dip"
        android:gravity="center"
        android:numColumns="auto_fit"  
        android:layout_marginTop="5dip" 
         android:layout_below="@id/ll_vt_header"
        android:stretchMode="columnWidth"
        android:verticalSpacing="10dip" />

</RelativeLayout>

 

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content" >  
  
    <ImageView   
        android:id="@+id/imageView"  
        android:layout_width="100dip"  
        android:layout_height="100dip"  
        android:src="@drawable/default_image"  
        android:layout_centerInParent="true"  
        />  
  
</RelativeLayout>

 

【RH850/U2A】:HSM与APP通信(中断方式) HSM与APP通信(中断方式) 阅读详情

相关推荐

Autodesk全家桶:从AutoCAD到Maya,设计师必备的7款神器全解析

本文全面解析Autodesk全家桶中的7款设计师必备软件,包括AutoCAD、Revit、Inventor、Fusion 360、Maya和3ds Max等。从二维制图到三维建模,从建筑信息模型(BIM)到影视动画制作,这些工具在工程设计、建筑可视化和数字创意领域展现出强大的协同效应。通过实战案例展示如何整合工作流,显著提升设计效率与项目质量。

weixin_29237635的博客 461

listview和gridView中findViewWithTag的使用

|举报|字号 订阅 listview的 只需要两步: 第一步: 首先在listview中设置一个tag标签例如  tv.setTag(position); 第二步: 获取的时候使用 TextView t=(TextView) listview.findViewWithTag(position).findViewById(R.id.tv);

u013598111的专栏 3700

GIS应用技巧之三招搞定重叠区域数据提取

在很多分析过程中,常常需要分析判断哪些图形发生了重叠,该重叠情况的发生在对应分析环境下具有特定意义。例如在缓冲区分析中,若两个受灾点周边的受灾面积(即缓冲区)有所重叠,分析重叠区域的受灾影响时,就需要考虑相互影响的因素。本例中先用【要素转面】工具提取出发生重叠的区域,其次用【空间连接】工具将原始图层信息连接到重叠数据的图层,分析重叠数据的属性表,即可得到发生重叠的原始图层数据。 Step1 提取重叠区属数据。打开【数据管理工具】|【要素】|【要素转面】工具,输入要素设置为“circles”,输出要素类设置为

端木宛白的博客家园 6万+

Android 使用开源库StickyGridHeaders来实现带sections和headers的GridView显示本地图片效果...

转载请注明本文出自xiaanming的博客(http://blog.youkuaiyun.com/xiaanming/article/details/20481185),请尊重他人的辛勤劳动成果,谢谢! 大家好!过完年回来到现在差不多一个月没写文章了,一是觉得不知道写哪些方面的文章,没有好的题材来写,二是因为自己的一些私事给耽误了,所以过完年的第一篇文章到现在才发表出来,2014年我还是会继续在优快云上面更...

maozhuxigood 329

ABAP BOM展开避坑指南:CS_BOM_EXPL_MAT_V2函数参数配置详解

本文深入解析了SAP ABAP开发中用于物料清单展开的核心函数CS_BOM_EXPL_MAT_V2。针对其复杂的参数配置,如CAPID、STLAN、DATUV和MEHRS,提供了详细的避坑指南和最佳实践,帮助开发者避免数据错误与性能陷阱,实现高效、准确的BOM多层展开。

pea55的博客 856

薄膜电容寿命预测全解析:从理论到实践,5步搞定可靠性评估

本文全面解析薄膜电容寿命预测的理论与实践,提供五步可靠性评估流程,涵盖温度应力、电压应力等关键因素分析,并分享提升寿命的实用技巧。特别适用于新能源、电动汽车等领域的设计工程师,帮助准确预测薄膜电容在实际工况下的使用寿命。

weixin_33712987的博客 435

Android GridView 异步加载图片

网上的资源普遍上是ListView异步加载图片,比较少有GirdView异步加载图片,参考了ListView异步加载图片的做法把GridView的异步加载图片功能做出来,方法和思想大同小异,本文章把GridView异步加载内存卡和网络图片lia希望对大家有用。

lanpy88的专栏 2万+

4、基于抽象解释的静态分析器中的跟踪分区与ASTRÉE分析器解析

本博客探讨了基于抽象解释的静态分析器中的跟踪分区技术,并深入解析了ASTRÉE分析器的工作原理和应用。通过示例程序说明了跟踪分区如何提升分析精度,减少误报,以及ASTRÉE如何利用多种数值抽象域(如八角形域、浮点区间线性形式等)来处理复杂的嵌入式C程序。此外,还讨论了ASTRÉE的模块化设计、循环展开优化、用户断言与自动细化的局限性等内容,为保障嵌入式软件的安全性和可靠性提供了理论与实践支持。

kotlin6android的博客 117

Android性能优化

1.布局优化 1. 避免overdraw Enable GPU Overdraw  Android系统在开发者选项中提供了这样一个工具“Enable GPU Overdraw”,通过这个工具可以查看当前区域中的绘制次数,从而尽量优化绘图层次,尽量增大蓝色区域,减少红色区域。 2. 优化布局层级 1)降低View树的高度 2)尽量使用RelativeLayout代替L

梦想是会飞的猪的博客 550

搭建ROS小车真的难吗?

搭建ROS小车真的难吗?不难 1.引言 本着为大家谋福利的心态,根据自己以往的开发经验,打算写一个从零开始制作一个可以实现地图构建和导航的ROS小车。目前某宝上面有很多现成产品,但是我个人认为,一个好的移动机器人开发工程师,应该对机器人的整个流程都能具备维护的能力,然后再深入研究其中一个方向即可。看到网上很少有整个系列的开发教程,看到同学们大多东拼西凑,浪费了不少时间。我就想着利用空余时间,将我本人的开发过程输出给大家。有基础理论、有实际工程代码、有丰富的学习资料,尽最大努力帮大家进入移动机器人的大门。 国

「小白学移动机器人」一个专注分享移动机器人相关知识的公众号! 1万+

ubuntu下安装多版本cuda及版本切换教程

首先,从官网下载所需版本的cuda安装包,下载链接。选择对应版本后,会跳转到该版本的配置信息页面。比如我是ubuntu20.04系统,已经安装好了cuda10.0,但是现在还需要用到cuda9.0。那么,在选定版本后,配置信息如下图所示(由于Version选项中没有20.04,因此我们随便选一个即可,这里选的16.04,这一选项不会影响后面的安装),Installer Type选择为runfile(因为使用deb文件进行安装的话,可能会将已经安装的较新的显卡驱动给替换掉),选择好之后点击Base Insta

zeeq的博客 3万+

android:tag与android:id的区别 findViewById与findViewWithTag的区别

布局文件中可以设置android:tag和android:id <android.support.v7.widget.RecyclerView android:id="@+id/recycler" android:layout_width="match_parent" android:layout_height="match_parent" andro...

情怀中的释然~ 1402

微信小程序 - 最新详细实现调起手机摄像头拍摄身份证人像面和国徽面取景框功能,在拍照相机上增加身份证证件照的轮廓或自定义文字,支持替换扫描拍摄辅助线图片及文本,小程序实现拍照身份证时带取景轮廓框拍摄!

微信小程序,身份证,证件照,人像,证件照提示框模板,vue身份证拍照框,摄像机相机里有引导内容,取景框拍摄,微信小程序实现拍照界面自定义实现,自拍人相框拍摄,取景框,户口簿取景框,画布指定区域生成图片,微信小程序身份证正反面拍照如何加入辅助图片引导照片,身份证取景框拍摄,服务器,上传,正反面,调起手机摄像头: 拍摄身份证的正反面,自定义身份证取景框,在相机上绘制 “身份证轮廓“ 与提示文字,拍摄身份证时出现人像框怎么实现,在相机上增加图片和文字,微信小程序怎么给调起的相机加入自定义图片,小程序实现给相机上面

🏆 前端领域优质创作者 3406

利用LruCache为GridView加载大量本地图片完整示例

MainActivity如下: package cc.testlrucache; import android.os.Bundle; import android.widget.GridView; import android.app.Activity; /** * Demo描述: * Android利用LruCache为GridView加载大量本地图片完整示例,防止OOM * *

谷哥的小弟 4134

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android 应用开发 之使用LruCache和DiskLruCache来在内存和SD卡中缓存图片

之前写过一篇文章,通过Android提供的AsyncTask和自己实现的ThreadPool两种方法来实现了图片数据的异步加载,但在实际应用中,仅仅做到这样是不够的。我们在GridView中加载了大量的图片数据,但当我们向上向下来回滚动的时候,之前加载过的图片都会重新从服务器中获取,这样显然不是很好的用户体验。对用户来说,在上下滚动的时候,曾经看过不久的图片能够马上显示出来,而不是要等待从服务器下

jonemill的专栏 642

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

android之GridView异步加载图片时显示加载进度ProgressBar

GridView异步加载图片时,每个view中先显示加载进度ProgressBar。。。Gallery中使用该方法还可以避免图片没加载到时无法滑动的问题。 GridView布局文件: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_w

谦言万语的专栏 3158

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

gridview第一个item是死的,其他的为真数据

首先感谢http://blog.youkuaiyun.com/self_study/article/details/46607815的分享。 效果图 借鉴下代码,内容只是适配器和gridview package com.zhao.album; import android.Manifest; import android.animation.ObjectAnimator; import and

小白的博客 1835

“应用程序已被java安全阻止”问题解决

 编写了一个java_pplet小程序,将其嵌入HTML程序中,运行时出现下面的问题。 解决办法:控制面板->程序->java->安全->编辑站点列表->添加->添加站点file:/ ->确定。

自由的代价永远是警惕 1万+

android 根据tag获取view,Android:如何使用View的setTag,getTag和findViewWithTag方法?

我的Android应用程序的代码段有一些麻烦.尝试设置ImageView对象的背景时,我会继续收到NullPointerException.以下是代码:public View getView(int position,View view,ViewGroup parent) {ImageView imageView;if (view == null) {imageView = new ImageVi...

weixin_33423874的博客 1117

java图片内存缓存_图片加载的基本思路,通过图片缓存来优化图片加载速度以及过于消耗流量的问题...

1 packagecom.bwf.market.loadimg;23 importjava.io.File;4 importjava.io.FileNotFoundException;5 importjava.io.FileOutputStream;6 importjava.io.InputStream;7 importjava.net.HttpURLConnection;8 importjava...

weixin_39653361的博客 725

Android 使用开源库StickyGridHeaders来实现带sections和headers的GridView显示本地图片效果

转载请注明本文出自xiaanming的博客(http://blog.youkuaiyun.com/xiaanming/article/details/20481185),请尊重他人的辛勤劳动成果,谢谢! 大家好!过完年回来到现在差不多一个月没写文章了,一是觉得不知道写哪些方面的文章,没有好的题材来写,二是因为自己的一些私事给耽误了,所以过完年的第一篇文章到现在才发表出来,2014年我还是会继续在优快云

lostinai的专栏 1067

android view setTag()和findViewWithTag()

android view setTag()和findViewWithTag()

zhouguizhi 1万+

GridView的三级缓存

public class PhotoWallAdapter extends BaseAdapter implements OnScrollListener { private List listCostumes; private Activity mActivity; private String path; /** * 记录所有正在下载或等待下载的任务。 */ private

无论是小草还是大树,我都不愿默默无闻! 951

Java Error: 应用程序已被Java安全阻止

我的Java版本是Java 8 Update 31打开Oracle E-Business Suite报Java安全性错误:错误内容:应用程序已被Java安全阻止出于安全原因,应用程序现在必须满足“高”或“非常高”安全设置的要求或属于“例外站点”列表的一部分才能允许运行。原因:您的安全设置已阻止自签名的应用程序运行解决方法:Java版本8,可以将此应用程序的 URL 添加到“例外站点”列表,该列表位

田攀的日志 3万+
上一篇: Tomcat6 Tomcat7对比测试
下一篇: Mongodb联合查询
yufei_java
博客等级 码龄10年 18粉丝 60原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值