android中获取本地图片,android 获取本地图片(二)

链接上一篇博文本篇博文接着讲述本地图片的获

链接上一篇博文

本篇博文接着讲述本地图片的获取。

下面给出获取本地图片的异步线程类LoadLoacalPhotoCursorTask的代码:

/**

* 获取本地图片的异步线程类

*/

public class LoadLoacalPhotoCursorTask extends AsyncTask {

private Context mContext;

private final ContentResolver mContentResolver;

ArrayList uriArray = (Context mContext) {

this.mContext = mContext;

mContentResolver = mContext.getContentResolver();

}

@Override

protected 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();

origIdArray = new ArrayList();

}

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 uriArray, ArrayList 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;

}

/**

* 图片异步加载线程类-任务线程

*/

{

private long origId;

private WeakReference imageViewReference;//指向Imageview的弱引用,把图片缓存在HashMap> bitmapCache中。

public LoadBitmapTask(ImageView imageView) {

imageViewReference = new WeakReference(imageView);

}

@Override

protected BitmapDrawable doInBackground(Long... params) {

origId = params[0];

Bitmap bitmap = null;

BitmapDrawable drawable = null;

// Wait here if work is paused and the task is not cancelled

synchronized (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(drawable));

}

return drawable;

}

@Override

protected void onPostExecute(BitmapDrawable drawable) {

if (isCancelled() || mExitTasksEarly) {

drawable = null;

}

final ImageView imageView = getAttachedImageView();

if (drawable != null && imageView != null) {

setImageDrawable(imageView, drawable);

}

}

@Override

protected 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 bitmapWorkerTaskReference;//虚引用

public AsyncDrawable(Resources res, Bitmap bitmap, LoadBitmapTask bitmapWorkerTask) {

super(res, bitmap);

bitmapWorkerTaskReference =

new WeakReference(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的区别。

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值