Android相册功能技术实现细节
来源:互联网 发布:youtube翻墙软件下载 编辑:程序博客网 时间:2024/06/06 14:10
最近的一个demo是模拟手Q中发送图片界面,它实际上是一个由缩略图组成的预览界面,在开发过程中,遇到两个问题:
因为该界面是由缩略图组成,如果直接将原始图片加载到内存中来处理,有可能导致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中@Overridepublic 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。
- Android相册功能技术实现细节
- android实现图片相册功能
- android 自定义view实现自动相册功能
- android自定义相册的功能实现
- android之照相、相册裁剪功能的实现过程
- Android实现图片(拍照+相册)上传功能
- Android之照相、相册裁剪功能的实现过程
- imageswitcher+gallay实现相册功能
- iOS 相册备份功能实现
- 自定义UICollectionViewFlowLayout实现相册功能
- Hexo+Github实现相册功能
- ionic 相册功能的实现
- android相机与相册功能
- android 技术细节整理
- Android ViewPager实现相册
- Android之相册实现
- 实现打开Android系统相册、照相机并实现照相,录像功能。
- Webgis 打印实现技术细节
- Java Code Output
- Activity状态的保存
- 又去天安门了!
- C++迭代器学习笔记
- 机器学习中的凸优化问题
- Android相册功能技术实现细节
- dll使用方法(转)
- HTTP协议深入学习_协议主体
- 条件变量基本概念和原理
- hdu 4125 Moles
- NULL 以及LONG等标识符无法识别的问题
- Android中的不同drawable文件夹所带来的思考
- uvalive 5742 TSP
- u-boot中的.balignl 16,0xdeadbeef的理解