Bitmapfun -- ImageFetcher类 翻译

来源:互联网 发布:网络专升本 编辑:程序博客网 时间:2024/04/30 19:10

自己手动翻译,英文水平一般,错误不可避免,将就下看…

/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package com.example.android.displayingbitmaps.util;import android.content.Context;import android.graphics.Bitmap;import android.net.ConnectivityManager;import android.net.NetworkInfo;import android.os.Build;import android.widget.Toast;import com.example.android.common.logger.Log;import com.example.android.displayingbitmaps.BuildConfig;import com.example.android.displayingbitmaps.R;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.File;import java.io.FileDescriptor;import java.io.FileInputStream;import java.io.IOException;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;/** * A simple subclass of {@link ImageResizer} that fetches and resizes images fetched from a URL. * 一个 ImageResizer 子类示例 , 它从一个URL 获取 和 调整 图片. * ImageResizer BitmapFun开源类 */public class ImageFetcher extends ImageResizer {    private static final String TAG = "ImageFetcher";    private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB    private static final String HTTP_CACHE_DIR = "http";    private static final int IO_BUFFER_SIZE = 8 * 1024;    //一块硬盘缓存        private DiskLruCache mHttpDiskCache;    //HTTP缓存文件    private File mHttpCacheDir;    //缓存状态    private boolean mHttpDiskCacheStarting = true;    //缓存锁    private final Object mHttpDiskCacheLock = new Object();    //缓存下标    private static final int DISK_CACHE_INDEX = 0;    /**     * Initialize providing a target image width and height for the processing images.     * 使用指定 目标图像宽度和高度 初始化图像     * @param context     * @param imageWidth     * @param imageHeight     */    public ImageFetcher(Context context, int imageWidth, int imageHeight) {        super(context, imageWidth, imageHeight);        init(context);    }    /**     * Initialize providing a single target image size (used for both width and height);     * 使用指定 目标图像 数据大小 初始化一个简单图像      * @param context     * @param imageSize     */    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);    }    //开始进入硬盘缓存    @Override    protected void initDiskCacheInternal() {        super.initDiskCacheInternal();        initHttpDiskCache();    }    //初始化硬盘缓存    private void initHttpDiskCache() {        if (!mHttpCacheDir.exists()) {            mHttpCacheDir.mkdirs();        }        //同步缓存锁        synchronized (mHttpDiskCacheLock) {            //取得可使用空间,判断是否 可以加载 预定义缓存大小            if (ImageCache.getUsableSpace(mHttpCacheDir) > HTTP_CACHE_SIZE) {                try {                    //打开或创建硬盘缓存                    mHttpDiskCache = DiskLruCache.open(mHttpCacheDir, 1, 1, HTTP_CACHE_SIZE);                    if (BuildConfig.DEBUG) {                        Log.d(TAG, "HTTP cache initialized");                    }                } catch (IOException e) {                    mHttpDiskCache = null;                }            }            mHttpDiskCacheStarting = false;            //唤醒所有等待 此锁的 线程            mHttpDiskCacheLock.notifyAll();        }    }    //清空缓存,并初始化    @Override    protected void clearCacheInternal() {        super.clearCacheInternal();        synchronized (mHttpDiskCacheLock) {            if (mHttpDiskCache != null && !mHttpDiskCache.isClosed()) {                try {                    mHttpDiskCache.delete();                    if (BuildConfig.DEBUG) {                        Log.d(TAG, "HTTP cache cleared");                    }                } catch (IOException e) {                    Log.e(TAG, "clearCacheInternal - " + e);                }                mHttpDiskCache = null;                mHttpDiskCacheStarting = true;                initHttpDiskCache();            }        }    }    //刷新缓存    @Override    protected void flushCacheInternal() {        super.flushCacheInternal();        synchronized (mHttpDiskCacheLock) {            if (mHttpDiskCache != null) {                try {                    mHttpDiskCache.flush();                    if (BuildConfig.DEBUG) {                        Log.d(TAG, "HTTP cache flushed");                    }                } catch (IOException e) {                    Log.e(TAG, "flush - " + e);                }            }        }    }    //关闭缓存    @Override    protected void closeCacheInternal() {        super.closeCacheInternal();        synchronized (mHttpDiskCacheLock) {            if (mHttpDiskCache != null) {                try {                    if (!mHttpDiskCache.isClosed()) {                        mHttpDiskCache.close();                        mHttpDiskCache = null;                        if (BuildConfig.DEBUG) {                            Log.d(TAG, "HTTP cache closed");                        }                    }                } catch (IOException e) {                    Log.e(TAG, "closeCacheInternal - " + e);                }            }        }    }    /**    * Simple network connection check.    * 判断网络连接示例    * @param context    */    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();            Log.e(TAG, "checkConnection - no connection found");        }    }    /**     * 重点来了,下载图片的主要方法     * The main process method, which will be called by the ImageWorker in the AsyncTask background thread.     * 一个主要的方法,ImageWorker 的 loadImage 方法 将会异步回调 此方法     * @param data The data to load the bitmap, in this case, a regular http URL     *             通过一个普通的URL载入图片到bitmap     * @return The downloaded and resized bitmap     *          一个下载完成并调整了大小的 bitmap     */    private Bitmap processBitmap(String data) {        if (BuildConfig.DEBUG) {            Log.d(TAG, "processBitmap - " + data);        }        //取得data 的hash值。设置为缓存键        final String key = ImageCache.hashKeyForDisk(data);        //一个文件描述符 ,        FileDescriptor fileDescriptor = null;        //文件输入流        FileInputStream fileInputStream = null;        //硬盘缓存快照        DiskLruCache.Snapshot snapshot;        //判断缓存是否在初始化,或者释放中        synchronized (mHttpDiskCacheLock) {            // Wait for disk cache to initialize            // 等待 初始化,或者释放 完成            while (mHttpDiskCacheStarting) {                try {                    mHttpDiskCacheLock.wait();                } catch (InterruptedException e) {}            }            //判断是否存在缓存文件            if (mHttpDiskCache != null) {                try {                    //根据 Key 取得快照                    snapshot = mHttpDiskCache.get(key);                    //判断文件快照是否存在,不存在则下载文件                    if (snapshot == null) {                        if (BuildConfig.DEBUG) {                            Log.d(TAG, "processBitmap, not found in http cache, downloading...");                        }                        //取得一个缓存编辑器,用于写入缓存文件                        DiskLruCache.Editor editor = mHttpDiskCache.edit(key);                        if (editor != null) {                            //从网络上下载文件流,并写入缓存文件流                            if (downloadUrlToStream(data,editor.newOutputStream(DISK_CACHE_INDEX))) {                                //编辑提交                                editor.commit();                            } else {                                //编辑取消                                editor.abort();                            }                        }                        //取得缓存文件快照                        snapshot = mHttpDiskCache.get(key);                    }                    //判断文件快照是否存在,存在则返回缓存文件数据流及文件描述符                    if (snapshot != null) {                        //文件流                        fileInputStream =(FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX);                        //描述符                        fileDescriptor = fileInputStream.getFD();                    }                } catch (IOException e) {                    Log.e(TAG, "processBitmap - " + e);                } catch (IllegalStateException e) {                    Log.e(TAG, "processBitmap - " + e);                } finally {                    if (fileDescriptor == null && fileInputStream != null) {                        try {                            fileInputStream.close();                        } catch (IOException e) {}                    }                }            }        }        //以下开始初始化Bitmap 文件        Bitmap bitmap = null;        if (fileDescriptor != null) {            //根据 文件描述符,图片预定义高度宽度,文件缓存 初始化Bitmap            bitmap = decodeSampledBitmapFromDescriptor(fileDescriptor, mImageWidth,mImageHeight, getImageCache());        }        if (fileInputStream != null) {            try {                fileInputStream.close();            } catch (IOException e) {}        }        return bitmap;    }    //重写 processBitmap 调用私有方法processBitmap    @Override    protected Bitmap processBitmap(Object data) {        return processBitmap(String.valueOf(data));    }    /**     * Download a bitmap from a URL and write the content to an output stream.     * 通过一个URL下载一个Bitmap文件,并写入输出流     *     * @param urlString The URL to fetch     *                  文件URL     * @return true if successful, false otherwise     *     */    public boolean downloadUrlToStream(String urlString, OutputStream outputStream) {        //修复SDK BUG 不用管        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;        } catch (final IOException e) {            Log.e(TAG, "Error in downloadBitmap - " + e);        } finally {            if (urlConnection != null) {                urlConnection.disconnect();            }            try {                if (out != null) {                    out.close();                }                if (in != null) {                    in.close();                }            } catch (final IOException e) {}        }        return false;    }    /**     * Workaround for bug pre-Froyo, see here for more info:     * http://android-developers.blogspot.com/2011/09/androids-http-clients.html     */    public static void disableConnectionReuseIfNecessary() {        // HTTP connection reuse which was buggy pre-froyo        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) {            System.setProperty("http.keepAlive", "false");        }    }}
0 0