Android ImageSwitcher 和 Gallery 浏览图片时 OutofMemory问题的解决


网上有很多例子介绍 ImageSwitcher 和 Gallery 配合浏览图片(其实看起来都是从一个来源拷贝的),大部分都有两个问题:

1、只讲了如何浏览应用内置资源,而没有给出浏览SD卡上图片的方法;

2、没有提到实际应用中会碰到的问题,就是内存不足的异常。


其中第一个问题有少数例子提到了解决方法,而第二个问题迄今为止尚未看到有人讨论。本人参考了一些资料,找到一种解决方法如下:


  1. 首先让自定义的ImageAdapter保存一个图片目录路径,用File.listFiles() 方法列出所有图片文件(根据需要,可能要排除一些非图片文件);
  2. 在需要时用 BitmapFactory.decodeFile() 解码出图片 的位图,在ImageAdapter 的  getView方法中,用ImageView.setImageBitmap()方法指定图片的位图;
  3. 将解码出的图片Bitmap用SoftReference保存,作为缓存,并便于系统需要内存时能够自动释放;
  4. 在Gallery 的 OnItemSelectedListener.onItemSelected() 方法中,不用ImageSwitcher.setImageURI方法,而是尝试从缓存中提取图片位图(这一点很关键!),设置ImageSwitcher中的ImageView。

参考代码:

public class ImageAdapter extends BaseAdapter {
		private Context mContext;
		private String imgFolder;
		List<File> imgFileList = new ArrayList<File>();
		List<SoftReference<Bitmap>> imageRefLst = new ArrayList<SoftReference<Bitmap>>();
		List<SoftReference<Bitmap>> thumbRefLst = new ArrayList<SoftReference<Bitmap>>();
		BitmapFactory.Options bfOpt;
		
		
		public ImageAdapter(Context c,String asImageFolder) {
			mContext = c;
			imgFolder = asImageFolder;
			imgFileList.addAll(Arrays.asList(new File(imgFolder).listFiles()) );
			for (File f:imgFileList){
				if (".nomedia".equals(f.getName())){
					imgFileList.remove(f);
					break;
				}
			}
			Log.d(LOG_TAG, "Image count :"+imgFileList.size());
			//防止大图片内存不足
			bfOpt =  new BitmapFactory.Options();
//			bfOpt.inTempStorage = new byte[1024*1024*10]; //10MB的临时存储空间
			bfOpt.inSampleSize = 4;

		}

		public int getCount() {
			return imgFileList.size();
		}

		public Object getItem(int position) {
			return position;
		}

		public long getItemId(int position) {
			return position;
		}

		public View getView(int position, View convertView, ViewGroup parent) 
		{
			ImageView imgView;
			if (convertView !=null && convertView instanceof ImageView){
				imgView = (ImageView) convertView;
			}else{
				imgView = new ImageView(mContext); 
				imgView.setAdjustViewBounds(true);
				imgView.setLayoutParams(new Gallery.LayoutParams(
					LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
				imgView.setImageBitmap(getImage(position));
			
//			i.setBackgroundResource(R.drawable.e);
			}
		
			return imgView;
		}

		public Bitmap getImage(int position)
		{
			return getImageFromList(imageRefLst,position);
		}
		public Bitmap getImageThumb(int position)
		{
			return getImageFromList(thumbRefLst,position);
		}
		private Bitmap getImageFromList(List<SoftReference<Bitmap>> imgRefLst,int position)
		{
			Bitmap img = null;
			//First get it from cache
			if (position>=0 && position<imgRefLst.size() && imgRefLst.get(position)!=null )
				img = imgRefLst.get(position).get();
			if (img==null){
				Log.d(LOG_TAG,"Loading image:"+imgFileList.get(position));
				if (imgRefLst == imageRefLst){
					bfOpt.inSampleSize = 1;
				}else{
					bfOpt.inSampleSize = 8;
				}
				img =  BitmapFactory.decodeFile(imgFileList.get(position).getAbsolutePath(),bfOpt); //这里bfOpt为Options属性
				
				imgRefLst.add(position, new SoftReference<Bitmap>(img));
			}
			return img;
		}
	}

OnItemSelectedListener.OnItemSelected():


	@Override
	public void onItemSelected(AdapterView<?> parent, View view, int position,
			long id) 
	{
		if (lastItemPosition == position)
			return;
		
//		imgSwitcher.setImageURI(Uri.fromFile(imgAdapter.imgFileList.get(position))); //太耗内存!改为以下几行:
		ImageView image = (ImageView)imgSwitcher.getNextView();
        image.setImageBitmap(imgAdapter.getImage(position));
        //调整动画方式,可不要
        if (lastItemPosition > position){
        	imgSwitcher.setInAnimation(slideInLeft);
			imgSwitcher.setOutAnimation(slideOutRight);
        }else{
        	imgSwitcher.setInAnimation(slideInRight);
			imgSwitcher.setOutAnimation(slideOutLeft);
        }
        imgSwitcher.showNext();
        //记录
        lastItemPosition = position;
		
	}


资源下载链接为: https://pan.quark.cn/s/5c50e6120579 在Android移动应用开发中,定位功能扮演着极为关键的角色,尤其是在提供导航、本地搜索等服务,它能够帮助应用获取用户的位置信息。以“baiduGPS.rar”为例,这是一个基于百度地图API实现定位功能的示例项目,旨在展示如何在Android应用中集成百度地图的GPS定位服务。以下是对该技术的详细阐述。 百度地图API简介 百度地图API是由百度提供的一系列开放接口,开发者可以利用这些接口将百度地图的功能集成到自己的应用中,涵盖地图展示、定位、路径规划等多个方面。借助它,开发者能够开发出满足不同业务需求的定制化地图应用。 Android定位方式 Android系统支持多种定位方式,包括GPS(全球定位系统)网络定位(通过Wi-Fi及移动网络)。开发者可以根据应用的具体需求选择合适的定位方法。在本示例中,主要采用GPS实现高精度定位。 权限声明 在Android应用中使用定位功能前,必须在Manifest.xml文件中声明相关权限。例如,添加<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />,以获取用户的精确位置信息。 百度地图SDK初始化 集成百度地图API,需要在应用启动初始化地图SDK。通常在Application类或Activity的onCreate()方法中调用BMapManager.init(),并设置回调监听器以处理初始化结果。 MapView的创建 在布局文件中添加MapView组件,它是地图显示的基础。通过设置其属性(如mapType、zoomLevel等),可以控制地图的显示效果。 定位服务的管理 使用百度地图API的LocationClient类来管理定位服务
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值