标签:
检测待加载图片的维度和类型信息的代码:
BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(getResources(), R.id.myimage, options);int imageHeight = options.outHeight;int imageWidth = options.outWidth;String imageType = options.outMimeType;
下面是相关代码:options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);options.inJustDecodeBounds = false;Bitmap bitmap = BitmapFactory.decodeResource(res, resId, options); //获得预期的缩小版Bitmap//下面的方法第二个是预期宽度,第三个是预期高度public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) {final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {final int halfHeight = height / 2;final int halfWidth = width / 2;while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) {inSampleSize *= 2;}}return inSampleSize;}
LruCache<String, Bitmap> mMemoryCache;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); //这是VM所能提供的最大内存使用数量,超过这个值将抛出OOM异常
final int cacheSize = maxMemory / 8;
mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
@Override protected int sizeOf(String key, Bitmap bitmap) {
return bitmap.getByteCount() / 1024; //根据记载图片实际大小计算size而不是根据图片数量
}
};private ImageFetcher mImageFetcher; mImageFetcher = new ImageFetcher(getActivity(), mImageThumbSize); mImageFetcher.setLoadingImage(R.drawable.empty_photo); mImageFetcher.addImageCache(getActivity().getSupportFragmentManager(), cacheParams);
mImageFetcher.flushCache(); mImageFetcher.closeCache(); mImageFetcher.clearCache(); mImageFetcher.setImageSize(height); mImageFetcher.setPauseWork(true); mImageFetcher.setExitTasksEarly(false);
private File mHttpCacheDir; //网络文件的缓存目录 private final Object mHttpDiskCacheLock = new Object(); //对象锁 private boolean mHttpDiskCacheStarting = true; //缓存初始化标志 private DiskLruCache mHttpDiskCache; //磁盘缓存对象 private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB //缓存文件最大容量
public ImageFetcher(Context context, int imageWidth, int imageHeight) {
super(context, imageWidth, imageHeight);
init(context);
}
public ImageFetcher(Context context, int imageSize) {
super(context, imageSize);
init(context);
}private void init(Context context) {
checkConnection(context);
mHttpCacheDir = ImageCache.getDiskCacheDir(context, HTTP_CACHE_DIR);
}
private void checkConnection(Context context) {
final ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo networkInfo = cm.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) { Toast.makeText(context, R.string.no_network_connection_toast, Toast.LENGTH_LONG).show(); }
}@Override protected void initDiskCacheInternal() {
super.initDiskCacheInternal();
initHttpDiskCache();
}
private void initHttpDiskCache() {
if (!mHttpCacheDir.exists()) { mHttpCacheDir.mkdirs(); } //note1
synchronized (mHttpDiskCacheLock) {
if (ImageCache.getUsableSpace(mHttpCacheDir) > HTTP_CACHE_SIZE) { //HTTP_CACHE_SIZE 等于 10MB
mHttpDiskCache = DiskLruCache.open(mHttpCacheDir, 1, 1, HTTP_CACHE_SIZE); //note2
}
mHttpDiskCacheStarting = false;
mHttpDiskCacheLock.notifyAll(); //note3
}
}@Override protected Bitmap processBitmap(Object data) {
return processBitmap(String.valueOf(data));
}
private Bitmap processBitmap(String data) {
final String key = ImageCache.hashKeyForDisk(data);
FileDescriptor fileDescriptor = null;
FileInputStream fileInputStream = null;
DiskLruCache.Snapshot snapshot;
synchronized (mHttpDiskCacheLock) {
while (mHttpDiskCacheStarting) {
try { mHttpDiskCacheLock.wait();} catch (InterruptedException e) {} //note1
}
if (mHttpDiskCache != null) {
try {
snapshot = mHttpDiskCache.get(key);
if (snapshot == null) {//note2
DiskLruCache.Editor editor = mHttpDiskCache.edit(key);
if (editor != null) {//note3
if (downloadUrlToStream(data,editor.newOutputStream(DISK_CACHE_INDEX))) {
editor.commit();
} else {editor.abort();}
}
snapshot = mHttpDiskCache.get(key);
}
if (snapshot != null) { //note4
fileInputStream = (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);
fileDescriptor = fileInputStream.getFD();
}
}
catch (IOException e) {.... }
finally {
if (fileDescriptor == null && fileInputStream != null) {
try { fileInputStream.close();} catch (IOException e) {}
}
}//end of finally
}//end of if
}//end of synchronized
Bitmap bitmap = null;
if (fileDescriptor != null) {
bitmap = decodeSampledBitmapFromDescriptor(fileDescriptor, mImageWidth, mImageHeight, getImageCache());//note5
}
if (fileInputStream != null) {
try { fileInputStream.close(); } catch (IOException e) {}
}
return bitmap;
}public boolean downloadUrlToStream(String urlString, OutputStream outputStream) {
disableConnectionReuseIfNecessary();
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
BufferedInputStream in = null;
try {
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE);
out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE);
int b;
while ((b = in.read()) != -1) { out.write(b); }
return true;
}
....
return false;
}protected int mImageWidth; protected int mImageHeight;
public ImageResizer(Context context, int imageWidth, int imageHeight) {
super(context);
setImageSize(imageWidth, imageHeight);
}
public ImageResizer(Context context, int imageSize) {
super(context);
setImageSize(imageSize);
}public void setImageSize(int width, int height) {
mImageWidth = width;
mImageHeight = height;
}
public void setImageSize(int size) {
setImageSize(size, size);
}public static Bitmap decodeSampledBitmapFromDescriptor( FileDescriptor fileDescriptor, int reqWidth, int reqHeight, ImageCache cache) {
final BitmapFactory.Options options = new BitmapFactory.Options(); // note1
options.inJustDecodeBounds = true;
BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); //note2
options.inJustDecodeBounds = false;
if (Utils.hasHoneycomb()) {addInBitmapOptions(options, cache);} //note3
return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options);
}protected Resources mResources; private ImageCache mImageCache; private Bitmap mLoadingBitmap; private ImageCache.ImageCacheParams mImageCacheParams; private final Object mPauseWorkLock = new Object(); protected boolean mPauseWork = false; //暂停标志位 private boolean mExitTasksEarly = false; //提前退出标志位
protected ImageWorker(Context context) {
mResources = context.getResources();
}public void setLoadingImage(Bitmap bitmap) {
mLoadingBitmap = bitmap;
}public void addImageCache(FragmentManager fragmentManager, ImageCache.ImageCacheParams cacheParams) {
mImageCacheParams = cacheParams;
mImageCache = ImageCache.getInstance(fragmentManager, mImageCacheParams);
new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE); //note1
}protected void initDiskCacheInternal() {
if (mImageCache != null) { mImageCache.initDiskCache(); }
}public void loadImage(Object data, ImageView imageView) {
if (data == null) { return; }
BitmapDrawable value = null;
if (mImageCache != null) {
value = mImageCache.getBitmapFromMemCache(String.valueOf(data)); //note1
}
if (value != null) { imageView.setImageDrawable(value); }
else if (cancelPotentialWork(data, imageView)) { //note2
final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView);
final AsyncDrawable asyncDrawable = new AsyncDrawable(mResources, mLoadingBitmap, task); //note3
imageView.setImageDrawable(asyncDrawable); //note4
task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR); //note5
}
}public static boolean cancelPotentialWork(Object data, ImageView imageView) {
final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); //note1
if (bitmapWorkerTask != null) {
final Object bitmapData = bitmapWorkerTask.mData; //note2
if (bitmapData == null || !bitmapData.equals(data)) { bitmapWorkerTask.cancel(true); }
else { return false; }
}
return true; //note3
}private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) {
if (imageView != null) {
final Drawable drawable = imageView.getDrawable();
if (drawable instanceof AsyncDrawable) {
final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
return asyncDrawable.getBitmapWorkerTask();
}
}
return null;
}public void setExitTasksEarly(boolean exitTasksEarly) {
mExitTasksEarly = exitTasksEarly;
setPauseWork(false);
}public void setPauseWork(boolean pauseWork) {
synchronized (mPauseWorkLock) {
mPauseWork = pauseWork;
if (!mPauseWork) {
mPauseWorkLock.notifyAll();
}
}
}private Object mData; private final WeakReference<ImageView> imageViewReference; //所引用,不影响垃圾回收
public BitmapWorkerTask(Object data, ImageView imageView) {
mData = data;
imageViewReference = new WeakReference<ImageView>(imageView);
}@Override protected BitmapDrawable doInBackground(Void... params) {
final String dataString = String.valueOf(mData);
Bitmap bitmap = null;
BitmapDrawable drawable = null;
synchronized (mPauseWorkLock) {
while (mPauseWork && !isCancelled()) { //note1
try { mPauseWorkLock.wait(); } catch (InterruptedException e) {}
}
}
if (mImageCache != null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = mImageCache.getBitmapFromDiskCache(dataString); //note2
}
if (bitmap == null && !isCancelled() && getAttachedImageView() != null && !mExitTasksEarly) {
bitmap = processBitmap(mData); //note3
}
if (bitmap != null) {
if (Utils.hasHoneycomb()) { drawable = new BitmapDrawable(mResources, bitmap); }//note4
else { drawable = new RecyclingBitmapDrawable(mResources, bitmap); }
if (mImageCache != null) { mImageCache.addBitmapToCache(dataString, drawable); } //note5
}
return drawable;
}@Override protected void onPostExecute(BitmapDrawable value) {
if (isCancelled() || mExitTasksEarly) {
value = null;
}
final ImageView imageView = getAttachedImageView();
if (value != null && imageView != null) {
setImageDrawable(imageView, value); //note1
}
}@Override protected void onCancelled(BitmapDrawable value) {
super.onCancelled(value);
synchronized (mPauseWorkLock) {
mPauseWorkLock.notifyAll(); //note1
}
}private LruCache<String, BitmapDrawable> mMemoryCache;//内存缓存图片
public static File getDiskCacheDir(Context context, String uniqueName) {
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
final String cachePath = ...获取一个绝对路径
return new File(cachePath + File.separator + uniqueName);
}标签:
原文地址:http://blog.csdn.net/evan_man/article/details/51347340