Android相册功能技术实现细节
2013-10-02 18:25
399 查看
最近的一个demo是模拟手Q中发送图片界面,它实际上是一个由缩略图组成的预览界面,在开发过程中,遇到两个问题:
因为该界面是由缩略图组成,如果直接将原始图片加载到内存中来处理,有可能导致OOM(一张图片是很大的,况且有很多张图片),如何有效的获取原始图片的缩略图呢?
在demo的第一版中,图片能正确加载到界面,可是当我去滑动gridView时,会非常卡,这是什么原因导致,又该如何处理呢?
又是各种度娘,google,问题最终还是解决了,这里总结一下解决方案。
有了这个属性,相应的方法就很简单了,可以先设置Options中有个inJustDecodeBounds为true,使用decodeFile获取图片的大小信息,计算出一个缩放比例(inSampleSize)后,再设置inJustDecodeBounds为false,将缩放后的图片加载到内存中。 具体代码如下:
问题解决,当然,这里还有很多优化的时候,比如在滑动GridView的时候,在它的滑动事件里,去recycle(对于那些不可见的convertView)相应的bitmap。
因为该界面是由缩略图组成,如果直接将原始图片加载到内存中来处理,有可能导致OOM(一张图片是很大的,况且有很多张图片),如何有效的获取原始图片的缩略图呢?
在demo的第一版中,图片能正确加载到界面,可是当我去滑动gridView时,会非常卡,这是什么原因导致,又该如何处理呢?
又是各种度娘,google,问题最终还是解决了,这里总结一下解决方案。
问题一:图片缩放
一般来说,取缩略图的方法是是使用BitmapFactory的decodeFile方法,通过BitmapFactory.Options的inSampleSize属性来控制缩放比例。属性值inSampleSize表示缩略图大小为原始的N分之几。然而,我们不可能将所有图片都加载到内存中来进行缩放操作,因为有些图片很大,而手机中内存又是很宝贵的,该怎么办呢?经研究发现,BitmapFactory.Options中有个inJustDecodeBounds属性,如果该值设置为true,,那么将不返回实际的bitmap,不给其分配实际的内存空间,而仅仅是一些图片大小信息。有了这个属性,相应的方法就很简单了,可以先设置Options中有个inJustDecodeBounds为true,使用decodeFile获取图片的大小信息,计算出一个缩放比例(inSampleSize)后,再设置inJustDecodeBounds为false,将缩放后的图片加载到内存中。 具体代码如下:
private Bitmap getBitmapFromUrl(String path){ Bitmap bitmap = null; //先从缓存中读取 bitmap = gridviewBitmapCaches.get(path); if (bitmap != null) { return bitmap; } BitmapFactory.Options options = new BitmapFactory.Options(); //设置inJustDecodeBounds为ture,来加载图片的边界信息 ptions.inJustDecodeBounds = true; bitmap = BitmapFactory.decodeFile(path, options); //计算出实际的缩放比例 int be = Math.min((int)(options.outHeight/(float)mImageHeight), (int)(options.outWidth/(float)mImageWidth)); if (be <= 0) { be = 1; } options.inSampleSize = be; //现在讲inJustDecodeBounds重新设置为false,获取实际的缩放后的图片 ptions.inJustDecodeBounds = false; bitmap=BitmapFactory.decodeFile(path,options); return bitmap; }
问题二:GridView滑动的时候卡
在demo刚成型的时候,发现在滑动GridView的时候是很卡的,仔细想了想,终于发现问题所在,因为我是在主线程来加载图片,并更新UI,这样,IO本身就是一个耗时的操作,若将图片加载放到主线程来执行,必然会阻塞IO。知道了问题所在,解决问题的方法也就有了,即异步来加载图片。 Android规定只有主线程能更新UI,并提供了一些在新线程中来更新UI的方式,其中最简单,最轻量的莫过于使用AsyncTask了,AsyncTask的具体用法可以查阅相关的文档,这里给出具体的实现代码://这个是在GridViewAdapter中 @Override public View getView(int position, View convertView, ViewGroup parent) { View view = converView; if (view == null) { view = getLayoutInflater().inflate(R.layout.qq_photo_select_item, null); } view.setLayoutParams(new GridView.LayoutParams(mImageWidth, mImageHeight)); PhotoInfo imageInfo = getItem(position); ImageView imageView = (ImageView) view .findViewById(R.id.photo_select_item_photo_iv); imageView.setAdjustViewBounds(false); String path = imageInfo.getPath(); AsyncLoadImageTask task = new AsyncLoadImageTask(imageView); task.execute(path); } //这里就是异步任务 private class AsyncLoadImageTask extends AsyncTask<String, Void, Bitmap> { private String url = null; private final WeakReference<ImageView> imageViewReference; public AsyncLoadImageTask(ImageView imageview) { super(); // TODO Auto-generated constructor stub imageViewReference = new WeakReference<ImageView>(imageview); } @Override protected Bitmap doInBackground(String... params) { Bitmap bitmap = null; this.url = params[0]; bitmap = getBitmapFromUrl(url); MainActivity.gridviewBitmapCaches.put(url, bitmap); return bitmap; } @Override protected void onPostExecute(Bitmap resultBitmap) { if (imageViewReference != null) { ImageView imageview = imageViewReference.get(); imageview.setImageBitmap(resultBitmap); } } }
问题解决,当然,这里还有很多优化的时候,比如在滑动GridView的时候,在它的滑动事件里,去recycle(对于那些不可见的convertView)相应的bitmap。
相关文章推荐
- Cocos2d-x 3.x 头像选择器,本地相册与拍照+头像编辑功能(Android、IOS双平台实现)
- Android 关于MQTT实现单聊和群聊功能,强大的技术
- android实现发送Email功能(从相册中选择图片作为附件)
- android之照相、相册裁剪功能的实现过程
- android自定义相册的功能实现
- Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
- 实现相册里面的修剪功能,How To Crop A Picture On Your Android Phone
- Android多点触控技术,实现对图片的放大缩小平移,惯性滑动等功能
- Android开发:仿微信和QQ空间发说说相册读取、拍照、图片裁剪和图片上传服务器等功能的实现
- Android 通过开源框架实现加载网络图片并下载到SD卡通知系统相册显示,(并实现分享图片功能)
- Android调用系统相机,相册,并实现图片剪裁功能
- Android实现从相册截图的功能
- Android开发技术学习之下拉刷新功能的实现
- Android调用系统相机以及拉取本地相册的功能实现以及代码分析
- Android之圆形头像(实现相机拍摄+相册选择+图片裁剪功能)
- Android ContentObserver实现截图后自动刷新相册(图库)的功能
- 实现打开Android系统相册、照相机并实现照相,录像功能。
- Android实现二维码扫描功能(四)-ZXing识别图片二维码,相册选图
- android 自定义view实现自动相册功能
- Android之---RecycleView实现简单的图片查看功能(类似相册查看器)