android 获取本地图片(二)

链接上一篇博文

本篇博文接着讲述本地图片的获取。 下面给出获取本地图片的异步线程类LoadLoacalPhotoCursorTask的代码:

/*** 获取本地图片的异步线程类*/public class LoadLoacalPhotoCursorTask extends AsyncTask<Object, Object, Object> {private Context mContext;private final ContentResolver mContentResolver;ArrayList<Uri> uriArray = (Context mContext) {this.mContext = mContext;mContentResolver = mContext.getContentResolver();}@Overrideprotected Object doInBackground(Object… params) {String[] projection = {MediaStore.Images.Media._ID};Uri ext_uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;String where = MediaStore.Images.Media.SIZE + “>=?”;/*** 这个查询操作完成图片大小大于100K的图片的ID查询。* 大家可能疑惑为什么不查询得到图片DATA呢?* 这样是为了节省内存。通过图片的ID可以查询得到指定的图片* 如果这里就把图片数据查询得到,手机中的图片大量的情况下* 内存消耗严重。那么,什么时候查询图片呢?应该是在Adapter* 中完成指定的ID的图片的查询,并不一次性加载全部图片数据*/Cursor c = MediaStore.Images.Media.query(mContentResolver,ext_uri,projection,where,new String[]{1 * 100 * 1024 + “”},MediaStore.Images.Media.DATE_ADDED+” desc”);int columnIndex = c.getColumnIndexOrThrow(MediaStore.Images.Media._ID);int i = 0;while (c.moveToNext() && i < c.getCount() && !mExitTasksEarly) { //移到指定的位置,遍历数据库long origId = c.getLong(columnIndex);uriArray.add(Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,origId + “”));origIdArray.add(origId);c.moveToPosition(i);i++;}c.close();//关闭数据库if (mExitTasksEarly) {uriArray = new ArrayList<Uri>();origIdArray = new ArrayList<Long>();}return null;}@Override(Object o) {if (onLoadPhotoCursor != null && !mExitTasksEarly) {/*** 查询完成之后,设置回调接口中的数据,把数据传递到Activity中*/onLoadPhotoCursor.onLoadPhotoSursorResult(uriArray, origIdArray);}}@Override() {super.onCancelled(); //To change body of overridden methods use File | Settings | File Templates.mExitTasksEarly = true;}(boolean exitTasksEarly) {this.mExitTasksEarly = exitTasksEarly;}(OnLoadPhotoCursor onLoadPhotoCursor) {this.onLoadPhotoCursor = onLoadPhotoCursor;}public interface OnLoadPhotoCursor {(ArrayList<Uri> uriArray, ArrayList<Long> origIdArray);}}

下面给出加载图片的类ImageWorker的代码:

/** * 手机本地图片异步加载处理类 * 图片的加载性能影响很大,使用弱引用和软引用 * 缓存图片,加快响应的速度,提高性能。 */public static final int FADE_IN_TIME = 200;Object mPauseWorkLock = Resources mResources;BitmapFactory.Options mOptions;Bitmap mLoadBitmap;//GridView中默认的背景图片//构造器public ImageWorker(Context context) {this.mResources = context.getResources();this.mContentResolver = context.getContentResolver();mOptions = new BitmapFactory.Options();mOptions.inSampleSize = 3;//缩放图片为原来的1/9。一般应用中加载图片都会进行图片的缩放,防止内存溢出的问题。这部分的内容有关Bitmap,请参考我的博文()}/*** 加载图片* @param origId 每个本地图片对应一个id值* @param imageView*/public void loadImage(long origId, ImageView imageView) {BitmapDrawable bitmapDrawable = null;(bitmapCache.containsKey(origId)) {bitmapDrawable = bitmapCache.get(origId).get();}if (bitmapDrawable != null) {imageView.setImageDrawable(bitmapDrawable);} else if (cancelPotentialWork(origId, imageView)) {final LoadBitmapTask loadBitmapTask = new LoadBitmapTask(imageView);final AsyncDrawable asyncDrawable =new AsyncDrawable(mResources, mLoadBitmap, loadBitmapTask);imageView.setImageDrawable(asyncDrawable);//SERIAL_EXECUTOR 启动线程,保证线程顺序依次执行loadBitmapTask.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, origId);}}/*** 该类提供这个方法设置GridView中每个item默认的图片*/public void setLoadBitmap(Bitmap mLoadBitmap) {this.mLoadBitmap = mLoadBitmap;}/*** 设置图片动画 加载图片渐隐渐显的效果** @param imageView* @param drawable*/private void setImageDrawable(ImageView imageView, Drawable drawable) {final TransitionDrawable td =new TransitionDrawable(new Drawable[]{new ColorDrawable(android.R.color.transparent),drawable});imageView.setImageDrawable(td);td.startTransition(FADE_IN_TIME);}/*** 取消可能在运行并且暂停的任务。** @param origId* @param imageView* @return*/private static boolean cancelPotentialWork(long origId, ImageView imageView) {final LoadBitmapTask loadBitmapTask = getBitmapWorkerTask(imageView);if (loadBitmapTask != null) {final long bitmapOrigId = loadBitmapTask.origId;if (bitmapOrigId == origId) {loadBitmapTask.cancel(true);} else {;}}return true;}/*** 图片异步加载线程类-任务线程*/<Long, Void, BitmapDrawable> {private long origId;private WeakReference<ImageView> imageViewReference;//指向Imageview的弱引用,把图片缓存在HashMap<Long, SoftReference<BitmapDrawable>> bitmapCache中。public LoadBitmapTask(ImageView imageView) {imageViewReference = new WeakReference<ImageView>(imageView);}@Overrideprotected BitmapDrawable doInBackground(Long… params) {origId = params[0];Bitmap bitmap = null;BitmapDrawable drawable = null;// Wait here if work is paused and the task is not cancelledsynchronized (mPauseWorkLock) {while (mPauseWork && !isCancelled()) {try {mPauseWorkLock.wait();} catch (InterruptedException e) {}}}if (bitmapCache != null && !isCancelled() && getAttachedImageView() != null&& !mExitTasksEarly) {//这里是根据图片的id值查询手机本地的图片,获取图片的缩略图,MICRO_KIND 代表96*96大小的图片bitmap = MediaStore.Images.Thumbnails.getThumbnail(mContentResolver,origId,MediaStore.Images.Thumbnails.MICRO_KIND,mOptions);}if (bitmap != null) {drawable = new BitmapDrawable(mResources, bitmap);bitmapCache.put(origId,new SoftReference<BitmapDrawable>(drawable));}return drawable;}@Overrideprotected void onPostExecute(BitmapDrawable drawable) {if (isCancelled() || mExitTasksEarly) {drawable = null;}final ImageView imageView = getAttachedImageView();if (drawable != null && imageView != null) {setImageDrawable(imageView, drawable);}}@Overrideprotected void onCancelled(BitmapDrawable drawable) {super.onCancelled(drawable);synchronized (mPauseWorkLock) {mPauseWorkLock.notifyAll();}}/*** 返回与此任务相关的ImageView,* 如果ImageView 内的任务是当前任务,* 则返回当前ImageView,否则返回null。* @return*/private ImageView getAttachedImageView() {final ImageView imageView = imageViewReference.get();final LoadBitmapTask bitmapWorkerTask = getBitmapWorkerTask(imageView);if (this == bitmapWorkerTask) {return imageView;}return null;}}/*** 存储异步信息图片资源类*/{private final WeakReference<LoadBitmapTask> bitmapWorkerTaskReference;//虚引用public AsyncDrawable(Resources res, Bitmap bitmap, LoadBitmapTask bitmapWorkerTask) {super(res, bitmap);bitmapWorkerTaskReference =new WeakReference<LoadBitmapTask>(bitmapWorkerTask);}public LoadBitmapTask getLoadBitmapTask() {return bitmapWorkerTaskReference.get();}}/*** 返回图片资源内存放的异步线程,如果存在,则返回,不存在,返回null。** @param imageView 当前存放异步资源图片的ImageView* @return*/private static LoadBitmapTask getBitmapWorkerTask(ImageView imageView) {if (imageView != null) {final Drawable drawable = imageView.getDrawable();if (drawable instanceof AsyncDrawable) {final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;return asyncDrawable.getLoadBitmapTask();}}return null;}/*** 设置异步任务是否暂停,false为启动,true为暂停。* @param pauseWork*/public void setPauseWork(boolean pauseWork) {synchronized (mPauseWorkLock) {mPauseWork = pauseWork;if (!mPauseWork) {mPauseWorkLock.notifyAll();}}}/*** 退出线程* @param exitTasksEarly*/public void setExitTasksEarly(boolean exitTasksEarly) {mExitTasksEarly = exitTasksEarly;setPauseWork(false);//这个设置为false,使得退出任务优雅。这个设置为true也是可行的,也没有问题,可以达到同样的效果。但是可以比较设置为true或false的区别。}}只有一条路不能选择——那就是放弃的路;

android 获取本地图片(二)

相关文章:

你感兴趣的文章:

标签云: