用心学Android之Bitmap缓存编,可为ListView等控件提供异步加载图片解决方案

           大体思路,先从LruCache取,没有开启新线程从缓存文件取,或从网络下载到缓存文件,再加载到LruCache中,代码已详细注释,不难理解。在网上找了好久没有理想的,就自己实现了一个,在此记录以备用。

       getBitmap 的参数 onlyFromCache 设置为true仅从缓存加载,为了UI滚动操作流畅,当UI滚动时,可设置此参数,只从缓存中加载,防止因开启新线程而导致UI操作不流畅。

import java.io.BufferedOutputStream;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileNotFoundException;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.net.MalformedURLException;

import java.net.URI;

import java.net.URISyntaxException;

import java.net.URL;

import java.util.HashSet;

import java.util.Set;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.regex.Pattern;

 

import android.content.res.Resources;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.Handler;

import android.os.Looper;

import android.support.v4.util.LruCache;

 

import com.zjg.Debug;

import com.zjg.MD5.MD5;

import com.zjg.youhuodong.Common;

 

public final class BitmapCache {

 

  public static class BitmapCacheException extends Exception {

 

    publicBitmapCacheException() {

      // TODO自动生成的构造函数存根

      super();

    }

 

    publicBitmapCacheException(String string) {

      // TODO自动生成的构造函数存根

      super(string);

    }

 

    publicBitmapCacheException(BitmapCacheException e) {

      // TODO自动生成的构造函数存根

      super(e);

    }

 

    /**

     *

     */

    private static final long serialVersionUID = 1L;

  }

 

  /**

   * 图片是否已准备好的监听器接口

   *

   * @author Administrator

   *

   */

  public interface OnImageReadyListener {

 

    // 图片已准备好

    void onReady(Bitmap bitmap, String url);

  }

 

  /**

   * 缓存

   */

  private static LruCache<String, Bitmap> memoryCache = null;

  /**

   * 缓存操作同步锁

   */

  private static Object memoryCacheSynchronizedLock = new Object();

  /**

   * 正在加入到缓存的key集合

   */

  private static Set<String> addingKeys = new HashSet<String>();

  /**

   * 正在加入到缓存的key集合的操作同步锁

   */

  private static Object addingKeysSynchronizedLock = new Object();

 

  /**

   * 创建缓存

   */

  private static void createBitmapCache() {

 

    // 获取虚拟机可用内存(内存占用超过该值的时候,将报OOM异常导致程序崩溃)。最后除以1024是为了以kb为单位

    if (memoryCache == null) {

      synchronized (memoryCacheSynchronizedLock) {

 

        if (memoryCache == null) {

          final int maxMemory = (int) (Runtime.getRuntime()

              .maxMemory() / 1024);

 

          // 使用可用内存的1/8来作为Memory Cache

          final int cacheSize = maxMemory / 8;

 

          memoryCache = new LruCache<String, Bitmap>(cacheSize) {

            @Override

            protected int sizeOf(String key, Bitmap bitmap) {

              // 重写sizeOf()方法,使用Bitmap占用内存的kb数作为LruCachesize

              return bitmap.getByteCount() / 1024;

            }

          };

        }

      }

    }

  }

 

  /**

   * 添加bitmap到缓存

   *

   * @param key

   * @param bitmap

   */

  private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

 

    // 调试log

    Thread currentThread = Thread.currentThread();

    Common.Log(currentThread.toString()

        + " | "

        + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

        + " | "

        + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {");

 

    if (memoryCache == null) {

      // 如果缓存没有建立,则建立缓存

 

      // 调试log

      Common.Log(currentThread.toString()

          + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

          + " | "

          + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

          + " | " + "  if (memoryCache == null){" + " |"

          + "    // 如果缓存没有建立,则建立缓存" + " |"

          + "    createBitmapCache();");

 

      createBitmapCache();

    }

 

    boolean adding = false;

    // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中

    synchronized (addingKeysSynchronizedLock) {

 

      // 调试log

      Common.Log(currentThread.toString()

          + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

          + " | "

          + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

          + " | " + "  // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中" + " |"

          + "  synchronized(addingKeysSynchronizedLock) {" + " | "

          + "  adding =addingKeys.contains(key);");

 

      adding = addingKeys.contains(key);

    }

 

    // 调试log

    Common.Log(currentThread.toString()

        + " | "

        + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

        + " | "

        + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

        + " | " + "  // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果" + " |"

        + "  adding =" + adding);

 

    // 如果相同key对应的bitmap正在被其它线程添加到缓存中,本线程进入等待状态

    if (adding) {

      try {

        synchronized (memoryCacheSynchronizedLock) {

 

          // 调试log

          Common.Log(currentThread.toString()

              + " |"

              + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

              + " | "

              + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

              + " | "

              + "    // // 如果相同key对应的bitmap正在被其它线程添加到缓存中,本线程进入等待状态"

              + " | "

              + "    if (adding) {"

              + " | "

              + "      synchronized(memoryCacheSynchronizedLock) {"

              + " | "

              + "     memoryCacheSynchronizedLock.wait();");

 

          memoryCacheSynchronizedLock.wait();

        }

      } catch (InterruptedException e) {

        // TODO自动生成的 catch

        e.printStackTrace();

      }

    }

 

    // 锁定共享资源,添加key到正在加入到缓存的key集合

    synchronized (addingKeysSynchronizedLock) {

 

      // 调试log

      Common.Log(currentThread.toString()

          + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

          + " | "

          + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

          + " | " + "      // 锁定共享资源,添加key到正在加入到缓存的key集合" + " | "

          + "      synchronized(addingKeysSynchronizedLock) {");

 

      addingKeys.add(key);

    }

    // 添加bitmap到缓存

    memoryCache.put(key, bitmap);

 

    // 锁定共享资源,从正在加入到缓存的key集合除去key

    synchronized (addingKeysSynchronizedLock) {

 

      // 调试log

      Common.Log(currentThread.toString()

          + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

          + " | "

          + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

          + " | " + "      // 锁定共享资源,从正在加入到缓存的key集合除去key" + " |"

          + "      synchronized(addingKeysSynchronizedLock) {");

 

      addingKeys.remove(key);

    }

    synchronized (memoryCacheSynchronizedLock) {

 

      // 调试log

      Common.Log(currentThread.toString()

          + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

          + " | "

          + "private static void addBitmapToMemoryCache(String key, Bitmapbitmap) {"

          + " | "

          + "  // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行"

          + " | " + "  synchronized(addingKeysSynchronizedLock) {"

          + " | " + "   memoryCacheSynchronizedLock.notifyAll();");

 

      // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行

      memoryCacheSynchronizedLock.notifyAll();

    }

  }

 

  /**

   * 根据key从缓存中取bitmap

   *

   * @param key

   * @return

   */

  private static Bitmap getBitmapFromMemCache(String key) {

    Debug.validateNullPointer(key);

    if (memoryCache == null) {

      createBitmapCache();

    }

 

    boolean adding = false;

    // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中

    synchronized (addingKeysSynchronizedLock) {

      adding = addingKeys.contains(key);

    }

    // 如果相同key对应的bitmap正在被其它线程添加到缓存中,本线程进入等待状态

    if (adding) {

      try {

        synchronized (memoryCacheSynchronizedLock) {

          memoryCacheSynchronizedLock.wait();

        }

      } catch (InterruptedException e) {

        // TODO自动生成的 catch

        e.printStackTrace();

      }

    }

    // 从缓存中取bitmap

    return memoryCache.get(key);

  }

 

  /**

   * 是否初始化标志

   */

  private static boolean bInitialize = false;

  /**

   * 初始化同步锁

   */

  private static Object initializeSynchronizedLock = new Object();

 

  /**

   * 下载Image的线程池

   */

  private static ExecutorService threadPool = null;

  /**

   * 线程池操作同步锁

   */

  private static Object threadPoolSynchronizedLock = new Object();

 

  /**

   * 线程数量,默认开启2线程

   */

  private static int threadCount = 2;

 

  /**

   * 资源管理器,用于加载"R.drawable.*"形式的以数字ID标识图片

   */

  private static Resources res = null;

 

  /**

   * 本地文件系统缓存目录

   */

  private static File cacheDir = null;

 

  /**

   * 初始化

   *

   * @param inContext

   * @param inCacheDir

   * @throws BitmapCacheException

   */

  public static void initialize(Resources inRes, File inCacheDir)

      throws BitmapCacheException {

    initialize(Debug.validateNullPointer(inRes),

        Debug.validateNullPointer(inCacheDir),threadCount);

  }

 

  /**

   * 初始化,默认开启2线程,可以根据情况设定

   *

   * @param inContext

   * @param inCacheDir

   * @param inThreadCount

   * @throws BitmapCacheException

   */

  public static void initialize(Resources inRes, File inCacheDir,

      int inThreadCount) throws BitmapCacheException {

    inRes = Debug.validateNullPointer(inRes);

    cacheDir = Debug.validateNullPointer(inCacheDir);

    threadCount = inThreadCount > 2 ? inThreadCount: threadCount;

 

    if (!bInitialize) {

      synchronized (initializeSynchronizedLock) {

        if (!bInitialize) {

          if (!cacheDir.exists()) {

            cacheDir.mkdirs();

          }

          if (!cacheDir.exists()) {

            throw new BitmapCacheException("\""

                + cacheDir.getAbsolutePath()

                + "\" failed to create the directory!");

          }

          threadPool = Executors.newFixedThreadPool(threadCount);

          bInitialize = true;

        }

      }

    }

 

  }

 

  /**

   * 取消正在下载的任务

   */

  public static void cancelTask() {

    if (threadPool != null) {

      synchronized (threadPoolSynchronizedLock) {

        threadPool.shutdownNow();

        threadPool =Executors.newFixedThreadPool(threadCount);

      }

    }

  }

 

  /**

   * 如果缓存命中,BitmapCache.getBitmap()会立即返回一个有效的Bitmap对象,可以立即使用它。

   * 如果没命中,就会开启新线程从缓存文件加载或从网络下载,这都是一个耗时的过程,

   * 这时BitmapCache.getBitmap()会立即返回null,应该检测这一情况并找一个临时替代方案。

   *

   * @param strUrl

   *            需要加载图片的url,可以是Android平台中"R.drawable.*"形式图片资源的数字ID标识,网络图片资源的url

   *            或本地图片文件的全路径名

   * @param hopeWidth

   *            期望的宽度

   * @param hopeHeight

   *            期望的高度

   * @paramonImageLoaderListener

   *            图片加载情况监听器

   *

   * @return缓存没命中返回null

   * @throwsBitmapCacheException

   */

  public static Bitmap getBitmap(String strUrl, int hopeWidth,

      int hopeHeight, OnImageReadyListener onImageLoaderListener)

      throws BitmapCacheException {

    return getBitmap(strUrl,hopeHeight, hopeHeight, onImageLoaderListener,

        false);

  }

 

  /**

   * 如果缓存命中,BitmapCache.getBitmap()会立即返回一个有效的Bitmap对象,可以立即使用它。

   * 如果没命中,就会开启新线程从缓存文件加载或从网络下载,这都是一个耗时的过程,

   * 这时BitmapCache.getBitmap()会立即返回null,应该检测这一情况并找一个临时替代方案。

   *

   * @param strUrl

   *            需要加载图片的url,可以是Android平台中"R.drawable.*"形式图片资源的数字ID标识,网络图片资源的url

   *            或本地图片文件的全路径名

   * @param hopeWidth

   *            期望的宽度,传入0或负值保持原图片宽度

   * @param hopeHeight

   *            期望的高度,传入0或负值保持原图片高度

   * @paramonImageLoaderListener

   *            图片加载情况监听器

   * @param onlyFromCache

   *            仅从缓存加载

   * @return缓存没命中返回null

   * @throwsBitmapCacheException

   */

  public static Bitmap getBitmap(String strUrl, int hopeWidth,

      int hopeHeight, OnImageReadyListener onImageLoaderListener,

      boolean onlyFromCache) throws BitmapCacheException {

    if (!bInitialize) {

      throw new BitmapCacheException("Not initialized!");

    }

 

    Debug.validateNullPointer(strUrl);

    Debug.validateNullPointer(onImageLoaderListener);

 

    // Android平台中"R.drawable.*"形式图片资源的数字ID标识

    if (isResourcesId(strUrl)){

      int id = Integer.parseInt(strUrl);

      return BitmapFactory.decodeResource(res, id);

    }

 

    // 试图从缓存中取

    Bitmapbitmap = getBitmapFromMemCache(strUrl);

    if (bitmap != null) {

      // 如果取到,返回结果

      return bitmap;

    }

 

    // 缓存中没有,就开启线程从网络或文件加载

    if (!onlyFromCache) {

      threadPool.execute(new AsyncLoadImageRunnable(strUrl, cacheDir,

          hopeWidth, hopeHeight,onImageLoaderListener));

    }

    return null;

  }

 

  /**

   * 判断是否是"R.drawable.*"形式的资源ID,通常是一串数字

   *

   * @param source

   * @return

   */

  private static boolean isResourcesId(String source) {

    // "^\\d+$"//非负整数(正整数 + 0

    // "^[0-9]*[1-9][0-9]*$"//正整数

    // "^((-\\d+)|(0+))$"//非正整数(负整数 + 0

    // "^-[0-9]*[1-9][0-9]*$"//负整数

    // "^-?\\d+$"//整数

    // "^\\d+(\\.\\d+)?$"//非负浮点数(正浮点数 + 0

    //"^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$"//正浮点数

    // "^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$"//非正浮点数(负浮点数 + 0

    // "^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"//负浮点数

    // "^(-?\\d+)(\\.\\d+)?$"//浮点数

 

    Stringreg = "^[0-9]*[1-9][0-9]*$";

    return Pattern.compile(reg).matcher(source).find();

  }

 

  /**

   * 正在下载的图片的文件名集合

   */

  private static Set<String> downloadFilenames = newHashSet<String>();

  /**

   * 正在下载的图片的文件名集合的操作同步锁

   */

  private static Object downloadFilenamesSynchornizedLock = new Object();

 

  /**

   * 下载图片的同步锁

   */

  private static Object downloadImageSynchronizedLock = new Object();

 

  /**

   * 异步加载图片Runnable

   *

   * @author周继光

   *

   */

  private static class AsyncLoadImageRunnable implements Runnable {

 

    private String strUrl;

    private File cacheDir;

    private int hopeWidth;

    private int hopeHeight;

    privateOnImageReadyListener onImageReadyListener;

 

    /**

     * @param strUrl

     * @param imageFilename

     * @param explicitURLImageFile

     * @param hopeWidth

     * @param hopeHeight

     * @param resultCallback

     */

    publicAsyncLoadImageRunnable(String strUrl, File cacheDir,

        int hopeWidth, int hopeHeight,

        OnImageReadyListeneronImageReadyListener) {

      super();

      this.strUrl = Debug.validateNullPointer(strUrl);

      this.cacheDir = Debug.validateNullPointer(cacheDir);

      this.hopeWidth = hopeWidth;

      this.hopeHeight = hopeHeight;

      this.onImageReadyListener = Debug

          .validateNullPointer(onImageReadyListener);

    }

 

    @SuppressWarnings("unused")

    @Override

    public void run() {

      // 调试log

      Thread currentThread = Thread.currentThread();

      Common.Log(currentThread.toString() + " | "

          + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

          + "  begin");

 

      String imageFilename = null;

      File file = null;

      URL url = parseURLString(strUrl);

      if (url != null) {

 

        // 调试log

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (url !=null) {");

 

        // 如果是一个网络资源

 

        // 提取图片文件后缀名

        Stringsuffix = getImageFileSuffix(strUrl);

 

        // 提取图片文件后缀名成功,URL提供的资源是一个明确的图片文件,否侧不是

        booleanexplicitURLImageFile = suffix.length() != 0;

 

        // URLMD5码值作图片的主文件名

        imageFilename= MD5.getMd5String(strUrl);

 

        if(explicitURLImageFile) {

 

          // 如果是一个明确的图片文件,沿用原后缀名

          imageFilename += suffix;

        } else {

 

          // 否则,用".jpg"做后缀名

          imageFilename += ".jpg";

        }

 

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (url !=null) {" + " |" + "    imageFilename="

            +imageFilename + " | " + "    strUrl=" + strUrl);

 

        boolean downloading = false;

        // 锁定共享资源,查询要下载的图片是否已有别的线程正在下载

        synchronized (downloadFilenamesSynchornizedLock) {

 

          // 调试log

          Common.Log(currentThread.toString()

              + " |"

              + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

              + " |"

              + "  if (url != null) {"

              + " |"

              + "    //锁定共享资源,查询要下载的图片是否已有别的线程正在下载"

              + " |"

              + "    synchronized(downloadFilenamesSynchornizedLock) {");

 

          downloading = downloadFilenames.contains(imageFilename);

        }

 

        // 调试log

        Common.Log(currentThread.toString()+ " | "

            + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (url !=null) {" + " |"

            + "    //查询要下载的图片是否已有别的线程正在下载,结果" + " | "

            + "   downloading=" + downloading);

 

        if (downloading) {

          // 如果已有别的线程正在下载相同的图片,本线程就进入等待状态

          try {

            synchronized (downloadImageSynchronizedLock) {

 

              // 调试log

              Common.Log(currentThread.toString()

                  + " |"

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |"

                  + "  if (url != null) {"

                  + " |"

                  + "    // 如果已有别的线程正在下载相同的图片,本线程就进入等待状态"

                  + " |"

                  + "    if (downloading) {"

                  + " |"

                  + "      synchronized(downloadImageSynchronizedLock) {"

                  + " |"

                  + "     downloadImageSynchronizedLock.wait();");

 

              downloadImageSynchronizedLock.wait();

            }

          } catch (InterruptedException e) {

            // TODO自动生成的 catch

            e.printStackTrace();

          }

        }

 

        // 试图从本地缓存目录中获取图片文件

        file= getFile(cacheDir, imageFilename);

 

        // 调试log

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (url !=null) {" + " |"

            + "    //试图从本地缓存目录中获取图片文件,结果" + " |" + "    file="

            +file);

 

        if (file != null) {

          // 从本地缓存目录中获取图片文件成功,取得文件大小

          int fileSize = 0;

          try {

            FileInputStreamfis;

            fis =new FileInputStream(file);

            fileSize= fis.available(); // 这就是文件大小

            fis.close();

          } catch (FileNotFoundException e) {

            // TODO自动生成的 catch

            e.printStackTrace();

          } catch (IOException e) {

            // TODO自动生成的 catch

            e.printStackTrace();

          }

 

          // 调试log

          Common.Log(currentThread.toString() + " | "

              + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

              + "  if (url != null) {" + " | "

              + "    if (file != null) {" + " | "

              + "        // 从本地缓存目录中获取图片文件成功,取得文件大小" + " | "

              + "        fileSize=" + fileSize);

 

          // 如果文件存在,并且大小为0,说明这是一个坏的文件,把它删除

          if (fileSize == 0) {

            file.delete();

            file= null;

          }

        }

 

        if (file == null) {

          // 如果没有从本地缓存目录中获取到文件

          // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

 

          // 调试log

          Common.Log(currentThread.toString() + " | "

              + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

              + "  if (url != null) {" + " | "

              + "    if (file == null) {" + " | "

              + "    // 如果没有从本地缓存目录中获取到文件" + " | "

              + "    // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中");

 

          // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中

          synchronized (downloadFilenamesSynchornizedLock) {

 

            // 调试log

            Common.Log(currentThread.toString()

                + " | "

                +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                + " | "

                + "  if (url !=null) {"

                + " | "

                + "    if (file== null) {"

                + " | "

                + "      // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中"

                + " | "

                + "     synchronized (downloadFilenamesSynchornizedLock) {");

 

            downloadFilenames.add(imageFilename);

          }

 

          try {

 

            // 调试log

            Common.Log(currentThread.toString()

                + " | "

                +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                + " | "

                + "  if (url !=null) {"

                + " | "

                + "    if (file== null) {"

                + " | "

                + "      // 开始下载图片"

                + " | "

                + "     url="

                + url

                + " | "

                + "      cacheDir="

                + cacheDir

                + " | "

                + "     imageFilename="

                +imageFilename

                + " | "

                + "     explicitURLImageFile="

                +explicitURLImageFile

                + " | "

                + "      file =downloadImageFromInternetToFile(url, cacheDir, imageFilename,explicitURLImageFile);");

 

            file= downloadImageFromInternetToFile(url, cacheDir,

                imageFilename,explicitURLImageFile);

 

            // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名

            synchronized (downloadFilenamesSynchornizedLock) {

 

              // 调试log

              Common.Log(currentThread.toString()

                  + " |"

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |"

                  + "  if (url != null) {"

                  + " |"

                  + "    if (file == null) {"

                  + " |"

                  + "      // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名"

                  + " |"

                  + "      synchronized(downloadFilenamesSynchornizedLock) {");

 

              downloadFilenames.remove(imageFilename);

            }

 

            // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

            synchronized (downloadImageSynchronizedLock) {

 

              // 调试log

              Common.Log(currentThread.toString()

                  + " |"

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |"

                  + "  if (url != null) {"

                  + " |"

                  + "    if (file == null) {"

                  + " |"

                  + "      // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行"

                  + " |"

                  + "      synchronized(downloadImageSynchronizedLock) {"

                  + " |"

                  + "     downloadImageSynchronizedLock.notifyAll();");

 

              downloadImageSynchronizedLock.notifyAll();

            }

 

          } catch (IOException e1) {

            // TODO自动生成的 catch

            e1.printStackTrace();

 

            // 发生异常,把已创建的文件删除

            if (file != null) {

 

              // 调试log

              Common.Log(currentThread.toString() + " | "

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |" + "  // 发生异常,把已创建的文件删除");

 

              if (file.exists()) {

                file.delete();

              }

            }

          } finally {

            // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

            synchronized (downloadFilenamesSynchornizedLock) {

 

              // 调试log

              Common.Log(currentThread.toString() + " | "

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |" + "  finally { " + " | "

                  + "// 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名");

 

              downloadFilenames.remove(imageFilename);

            }

 

            // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

            synchronized (downloadImageSynchronizedLock) {

 

              // 调试log

              Common.Log(currentThread.toString()

                  + " |"

                  + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                  + " |"

                  + "  finally { "

                  + " |"

                  + "// 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行");

 

              downloadImageSynchronizedLock.notifyAll();

            }

          }

        }

 

      } else {

 

        // 如果不是网络资源,就试图解析为一个本地文件

        file= getFile(strUrl);

 

        // 调试log

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (url !=null) { }else{ " + " | "

            + "    // 如果不是网络资源,就试图解析为一个本地文件" + " | " + "   file="

            +file);

      }

      if (file != null) {

 

        // 调试log

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + "  if (file !=null) {" + " |"

            + "    // 从文件里按要求加载图片,并缓存,然后返回结果" + " | " + "    file="

            +file);

 

        // 从文件里按要求加载图片,并缓存,然后返回结果

        BitmapFactory.OptionsbfOptions = new BitmapFactory.Options();

        bfOptions.inJustDecodeBounds = true;// 设置成了true,不占用内存,只获取bitmap宽高

        BitmapFactory.decodeFile(file.getAbsolutePath(),bfOptions);

 

        int imageWidth =bfOptions.outWidth;

        int imageHeight =bfOptions.outHeight;

 

        hopeWidth = hopeWidth <= 0 ?imageWidth : hopeWidth;

        hopeHeight = hopeHeight <= 0 ?imageHeight : hopeHeight;

 

        int inSampleSizeTmp1 =hopeWidth == imageWidth ? 1

            : (int) ((float) imageWidth / hopeWidth);

        int inSampleSizeTmp2 =hopeHeight == imageHeight ? 1

            : (int) ((float) imageHeight / hopeHeight);

        int inSampleSize =Math.max(1,

            Math.max(inSampleSizeTmp1,inSampleSizeTmp2));

        // 调整inSampleSize为不大于inSampleSize2的幂

        int nPowerBase2 = 1;

        while (nPowerBase2 <inSampleSize) {

          nPowerBase2 <<= 1;

        }

        inSampleSize= nPowerBase2 >> 1;

        bfOptions.inSampleSize =inSampleSize;

        // BitmapFactory.Options 用于指定解码时的一些设置:

        // 1inBitmap如果设置,当加载内容时该方法将尝试重用这个位图;

        // 2inDensity使用像素密度来表示位图;

        // 3inDither如果存在抖动,解码器将尝试解码图像抖动;

        // 4inPurgeable如果设置为true,则由此产生的位图将分配其像素,以便系统需要回收内存时可以将它们清除;

        // 5inInputShareableinPurgeable一起使用,如果inPurgeablefalse那该设置将被忽略,如果为true,那么它可以决定位图是否能够共享一个指向数据源的引用,或者是进行一份拷贝;

        // 6inJustDecodeBounds如果设置,那返回的位图将为空,但会保存数据源图像的宽度和高度;

        // 7inMutable如果设置,解码方法将始终返回一个可变的位图;

        // 8inPreferQualityOverSpeed如果设置为true,解码器将尝试重建图像以获得更高质量的解码,甚至牺牲解码速度;

        // 9inPreferredConfig 如果为非空,解码器将尝试解码成这个内部配置;

        // 10inSampleSize 如果设置的值大于1,解码器将等比缩放图像以节约内存;

        // 11inScaled如果设置,当inDensityinTargetDensity不为0,加载时该位图将被缩放,以匹配inTargetDensity,而不是依靠图形系统缩放每次将它绘制到画布上;

        // 12inScreenDensity当前正在使用的实际屏幕的像素密度;

        // 13inTargetDensity这个位图将被画到的目标的像素密度;

        // 14mCancel用于指示已经调用了这个对象的取消方法的标志;

        // 15outHeightoutWidth图像的高度和宽度;

        // 16outMimeType 如果知道,这个字符串将被设置为解码图像的MIME类型。

        // 如果inPurgeable设为True的话表示创建Bitmap时用于存储Pixel的内存空间在系统内存不足时可以被回收,在应用需要再次访问BitmapPixel时(如绘制Bitmap或是调用getPixel),系统会再次调用BitmapFactorydecoder重新生成BitmapPixel数组。为了能够重新解码图像,bitmap要能够访问存储Bitmap的原始数据。在inPurgeablefalse时表示创建的BitmapPixel内存空间不能被回收,这样BitmapFactory在不停decodeByteArray创建新的Bitmap对象,不同设备的内存不同,因此能够同时创建的Bitmap个数可能有所不同,200bitmap足以使大部分的设备重新OutOfMemory错误。当isPurgable设为true时,系统中内存不足时,可以回收部分Bitmap占据的内存空间,这时一般不会出现OutOfMemory错误。

 

        bfOptions.inJustDecodeBounds = false;// 这里一定要将其设置回false,因为之前我们将其设置成了true

        bfOptions.inPurgeable = true; // 使得内存可以被回收

 

        bfOptions.inInputShareable = true;

        bfOptions.inDither = false; // 图片不抖动

        bfOptions.inTempStorage = new byte[64 * 1024];

        // 自行开辟一段64K大小的内存空间,做为临时数据缓存

 

        FileInputStreamfis = null;

        try {

          fis = new FileInputStream(file);

        } catch(FileNotFoundException e) {

          // TODO自动生成的 catch

          e.printStackTrace();

        }

 

        try {

 

          final Bitmap bitmap = BitmapFactory.decodeFileDescriptor(

              fis.getFD(), null, bfOptions);

 

          // 调试log

          Common.Log(currentThread.toString() + " | "

              + Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

              + "  if (file != null) {" + " | "

              + "    // 从文件里按要求加载图片,并缓存,然后返回结果" + " | "

              + "    bitmap=" + bitmap);

 

          if (bitmap != null) {

 

            // 解码图片成功

            // 加入到缓存

 

            // 调试log

            Common.Log(currentThread.toString()

                + " | "

                +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE)

                + " | "

                + "  if (file !=null) {"

                + " | "

                + "    if(bitmap != null) {"

                + " | "

                + "      // 加入到缓存"

                + " | "

                + "     addBitmapToMemoryCache(strUrl, bitmap);");

 

            addBitmapToMemoryCache(strUrl, bitmap);

 

            // 寄送到主线程中执行

            new Handler(Looper.getMainLooper())

                .post(new Runnable() {

 

                  @Override

                  public void run() {

                    // TODO自动生成的方法存根

 

                    // 图片已准备好,回调监听器相应方法

                    if (onImageReadyListener != null) {

 

                      onImageReadyListener.onReady(

                          bitmap, strUrl);

                    }

                  }

                });

          }

        } catch (IOException e) {

          // TODO自动生成的 catch

          e.printStackTrace();

        }

 

        Common.Log(currentThread.toString()+ " | "

            +Debug.FILE_LINE_FUNC(Debug.CALL_PLACE) + " | "

            + " end");

      }

    }

 

    /**

     * 获取图片文件后缀名

     *

     * @param imageFilename

     * @return成功返回后缀名,包含"."字符,失败返回空字符串

     */

    private static StringgetImageFileSuffix(String imageFilename) {

      String suffix = imageFilename.substring(

          imageFilename.lastIndexOf(".")).toLowerCase();

      if (suffix.length() == 0) {

        return "";

      }

      String imageSuffix = ".jpg|.jpeg|.png|.bmp|.gif";

      // returnimageSuffix.indexOf(suffix) >= 0;

      if (imageSuffix.contains(suffix)) {

        return suffix;

      } else {

        return "";

      }

    }

 

    /**

     * 解析一个URI字符串为URI对象

     *

     * @param strURI

     * @return如果失败,返回null

     */

    private static URIparseURIString(String strURI) {

      if (strURI.split(":").length != 2) {

        return null;

      }

      try {

        return new URI(strURI);

      } catch (URISyntaxException e) {

        // TODO自动生成的 catch

        return null;

      }

    }

 

    /**

     * 解析一个URL字符串为URL对象

     *

     * @param strURL

     * @return如果失败,返回null

     */

    private static URLparseURLString(String strURL) {

      URI uri = parseURIString(strURL);

      if (uri == null) {

        return null;

      }

      try {

        return uri.toURL();

      } catch (MalformedURLException e) {

        // TODO自动生成的 catch

        return null;

      }

    }

 

    /**

     * 根据全路径名获取文件

     *

     * @param filename

     * @return成功返回File对象,文件不存在返回null

     */

    private static FilegetFile(String filename) {

      File file = new File(filename);

      if (file.exists() && file.isFile()) {

        return file;

      } else {

        return null;

      }

    }

 

    /**

     * 从指定的目录中根据文件名获取文件

     *

     * @param dir

     * @param filename

     * @return成功返回File对象,文件不存在返回null

     */

    private static File getFile(Filedir, String filename) {

      Debug.validateNullPointer(dir);

      Debug.validateNullPointer(filename);

 

      File file = new File(dir, filename);

      if (file.exists() && file.isFile()) {

        return file;

      }

      return null;

    }

 

    /**

     * 下载网络图片资源到文件

     *

     * @param url

     * @param cacheDir

     * @param imageFilename

     * @param explicitURLImageFile

     * @throws IOException

     */

    private static FiledownloadImageFromInternetToFile(URL url,

        FilecacheDir, String imageFilename,

        booleanexplicitURLImageFile) throws IOException {

      Debug.validateNullPointer(url);

      Debug.validateNullPointer(cacheDir);

      Debug.validateNullPointer(imageFilename);

 

      if (!cacheDir.exists()) {

        cacheDir.mkdirs();

      }

 

      File file = new File(cacheDir, imageFilename);

      if (!file.exists()) {

        file.createNewFile();

      }

 

      if (explicitURLImageFile) {

        saveStreamToFile(url.openStream(),file);

      } else {

        saveUrlImageToFile(url,file, Bitmap.CompressFormat.JPEG);

      }

      return file;

    }

 

    /**

     * 读取流保存到文件

     *

     * @param is

     * @param file

     * @throws IOException

     */

    private static void saveStreamToFile(InputStreamis, File file)

        throws IOException {

      Debug.validateNullPointer(is);

      Debug.validateNullPointer(file);

 

      if (!file.isFile()) {

        throw newIllegalArgumentException(Debug.FILE_LINE_FUNC()

            + "The parameter \"file\" is not a file!");

      }

 

      File dir = file.getParentFile();

      if (!dir.exists()) {

        dir.mkdirs();

      }

 

      if (!file.exists()) {

        file.createNewFile();

      }

 

      FileOutputStream fos = newFileOutputStream(file);

      BufferedOutputStream bfos = new BufferedOutputStream(fos);

      byte[] buffer = new byte[1024];

      int length = -1;

      while ((length = is.read(buffer)) != -1) {

        bfos.write(buffer,0, length);

      }

      bfos.flush();

      fos.flush();

      bfos.close();

      fos.close();

    }

 

    /**

     * 解码网络图片并保存到文件

     *

     * @param url

     * @param file

     * @param format

     * @throws IOException

     */

    private static voidsaveUrlImageToFile(URL url, File file,

        Bitmap.CompressFormatformat) throws IOException {

      Debug.validateNullPointer(url);

      Debug.validateNullPointer(file);

 

      if (!file.isFile()) {

        throw newIllegalArgumentException(Debug.FILE_LINE_FUNC()

            + "The parameter \"file\" is not afile!");

      }

 

      File dir = file.getParentFile();

      if (!dir.exists()) {

        dir.mkdirs();

      }

 

      String filename = file.getName();

      filename = filename.substring(0,filename.lastIndexOf("."));

      if (format == Bitmap.CompressFormat.JPEG) {

        filename+= ".jpg";

      } else if (format == Bitmap.CompressFormat.PNG) {

        filename+= ".png";

      } else if (format == Bitmap.CompressFormat.WEBP) {

        filename+= ".webp";

      }

 

      if (!filename.equals(file.getName())) {

        file= new File(dir, filename);

      }

 

      if (!file.exists()) {

        file.createNewFile();

      }

 

      Bitmap bitmap = BitmapFactory.decodeStream(url.openStream());

      FileOutputStream fos = newFileOutputStream(file);

      BufferedOutputStream bfos = newBufferedOutputStream(fos);

      bitmap.compress(format, 100, bfos);

      bfos.flush();

      fos.flush();

      bfos.close();

      fos.close();

      // 如果图片还没有回收,强制回收

      if (!bitmap.isRecycled()) {

        bitmap.recycle();

      }

    }

  }

}

 


               后记 ,中间的Log部分有点难看,是我用来调试的,目前对于多线程的调试我还没有找到有效的方法,只有采用Log大法,但这种方法很苦逼,如果那位大侠有好的方法还望不吝赐教。

      后附我的调试记录,供大家研究,重点关注黄色标记

 

01-04 19:16:29.186: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:29.187: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:29.193: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:29.246: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=ec9cd0efcc474d59d0806c51145d8d3f.jpg |     strUrl=http://img5.imgtn.bdimg.com/it/u=1021218502,348470389&fm=23&gp=0.jpg

01-04 19:16:29.247: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:29.247: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:29.310: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:29.311: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=4ea7aa268bc751856acde2cccf2c118e.jpg |     strUrl=http://img2.imgtn.bdimg.com/it/u=4104597529,935107043&fm=23&gp=0.jpg

01-04 19:16:29.311: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:29.312: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:29.403: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:29.403: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:29.404: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:29.404: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:29.405: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:29.405: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img5.imgtn.bdimg.com/it/u=1021218502,348470389&fm=23&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=ec9cd0efcc474d59d0806c51145d8d3f.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:29.406: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:29.413: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img2.imgtn.bdimg.com/it/u=4104597529,935107043&fm=23&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=4ea7aa268bc751856acde2cccf2c118e.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:37.367: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:37.368: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:37.369: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:37.369: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:37.370: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/ec9cd0efcc474d59d0806c51145d8d3f.jpg

01-04 19:16:37.400: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41ba3430

01-04 19:16:37.401: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:37.402: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:37.403: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:37.404: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:37.405: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:37.410: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:37.411: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:37.422: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:37.425: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:37.427: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:37.429: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=9728e9abfed0a203fa0039934a40d7a6.jpg |     strUrl=http://img2.imgtn.bdimg.com/it/u=156106435,3928380367&fm=21&gp=0.jpg

01-04 19:16:37.430: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:37.431: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:37.432: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:37.433: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:37.434: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:37.435: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img2.imgtn.bdimg.com/it/u=156106435,3928380367&fm=21&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=9728e9abfed0a203fa0039934a40d7a6.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:38.046: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:38.046: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:38.046: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:38.047: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:38.047: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/4ea7aa268bc751856acde2cccf2c118e.jpg

01-04 19:16:38.069: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@4172e5a0

01-04 19:16:38.070: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:38.071: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:38.071: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:38.072: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:38.073: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:38.074: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:38.075: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:38.076: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:38.076: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:38.077: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:38.078: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=19e83432b35c96946650ce1046d1d390.jpg |     strUrl=http://img1.imgtn.bdimg.com/it/u=2385359044,1236744741&fm=23&gp=0.jpg

01-04 19:16:38.079: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:38.079: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:38.080: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:38.081: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:38.082: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:38.082: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img1.imgtn.bdimg.com/it/u=2385359044,1236744741&fm=23&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=19e83432b35c96946650ce1046d1d390.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:42.430: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:42.430: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:42.431: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:42.431: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:42.432: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/9728e9abfed0a203fa0039934a40d7a6.jpg

01-04 19:16:42.449: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41b9e330

01-04 19:16:42.450: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:42.450: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:42.450: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:42.451: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:42.452: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:42.453: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:42.454: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:42.460: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:42.463: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:42.464: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:42.466: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=71615a30de2cd3603574ea535ee892cb.jpg |     strUrl=http://img4.imgtn.bdimg.com/it/u=98585476,3661901922&fm=23&gp=0.jpg

01-04 19:16:42.467: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:42.469: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:42.471: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:42.473: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:42.474: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:42.474: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img4.imgtn.bdimg.com/it/u=98585476,3661901922&fm=23&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=71615a30de2cd3603574ea535ee892cb.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:44.207: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:44.207: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:44.208: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:44.208: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:44.209: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/19e83432b35c96946650ce1046d1d390.jpg

01-04 19:16:44.233: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@4184ed90

01-04 19:16:44.234: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:44.234: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:44.235: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:44.235: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:44.236: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:44.237: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:44.237: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:44.238: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:44.238: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:44.242: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:44.242: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=f6063e13b88934077c31cca4d7eb6a03.jpg |     strUrl=http://img5.imgtn.bdimg.com/it/u=3800844976,1135443821&fm=21&gp=0.jpg

01-04 19:16:44.243: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:44.244: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:44.245: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:44.245: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:44.246: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:44.247: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://img5.imgtn.bdimg.com/it/u=3800844976,1135443821&fm=21&gp=0.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=f6063e13b88934077c31cca4d7eb6a03.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:47.151: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:47.151: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:47.151: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:47.152: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:47.152: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/71615a30de2cd3603574ea535ee892cb.jpg

01-04 19:16:47.168: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41c87650

01-04 19:16:47.168: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:47.169: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:47.169: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:47.170: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:47.171: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:47.172: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:47.172: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:47.173: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:47.173: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:47.174: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:47.176: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |     strUrl=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg

01-04 19:16:47.176: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:47.177: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:16:47.178: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=null

01-04 19:16:47.179: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:662|FUNC:run] |   if (url != null) { |     if (file == null) { |     // 如果没有从本地缓存目录中获取到文件 |     // 就试图从网上下载并以文件的形式保存图片到本地缓存目录中

01-04 19:16:47.179: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:674|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,把要下载的图片文件名加入到正在下载图片文件名集合中 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:47.180: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:692|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 开始下载图片 |       url=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg |       cacheDir=/mnt/sdcard/com.zjg.youhuodong/image_cache |       imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |       explicitURLImageFile=true |       file = downloadImageFromInternetToFile(url, cacheDir, imageFilename, explicitURLImageFile);

01-04 19:16:47.492: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:47.493: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:16:47.505: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:16:47.506: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:16:47.506: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/f6063e13b88934077c31cca4d7eb6a03.jpg

01-04 19:16:47.535: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41bab240

01-04 19:16:47.535: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:16:47.536: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:16:47.536: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:16:47.536: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:16:47.537: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:47.537: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:16:47.538: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:16:47.546: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:16:47.546: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:16:47.549: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:16:47.549: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |     strUrl=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg

01-04 19:16:47.550: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:16:47.550: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=true

01-04 19:16:47.550: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:595|FUNC:run] |   if (url != null) { |     // 如果已有别的线程正在下载相同的图片,本线程就进入等待状态 |     if (downloading) { |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.wait();

01-04 19:17:03.069: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:723|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 锁定共享资源,下载成功,从正在下载图片文件名集合中移除已下载的图片文件名 |       synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:17:03.069: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:742|FUNC:run] |   if (url != null) { |     if (file == null) { |       // 通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行 |       synchronized (downloadImageSynchronizedLock) { |       downloadImageSynchronizedLock.notifyAll();

01-04 19:17:03.070: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:779|FUNC:run] |   finally {  | // 即使发生异常,也应该从正在下载图片文件名集合中移除已下载的图片文件名

01-04 19:17:03.070: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.070: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:792|FUNC:run] |   finally {  | // 即使发生异常,也必须通知等待本线程下载图片的其他线程,唤醒它们以让它们继续执行

01-04 19:17:03.070: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:643|FUNC:run] |   if (url != null) { |     if (file != null) { |         // 从本地缓存目录中获取图片文件成功,取得文件大小 |         fileSize=330853

01-04 19:17:03.070: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.071: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.158: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41724320

01-04 19:17:03.158: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:17:03.159: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:17:03.159: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:17:03.162: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:17:03.163: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.163: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.164: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:17:03.174: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:17:03.175: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:17:03.177: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:17:03.179: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |     strUrl=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg

01-04 19:17:03.180: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:17:03.181: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:17:03.181: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.182: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:643|FUNC:run] |   if (url != null) { |     if (file != null) { |         // 从本地缓存目录中获取图片文件成功,取得文件大小 |         fileSize=330853

01-04 19:17:03.186: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.230: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@416e4138

01-04 19:17:03.230: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:17:03.231: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:17:03.232: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:17:03.234: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:17:03.239: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.245: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.246: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:17:03.246: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:17:03.247: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:17:03.248: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:17:03.248: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |     strUrl=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg

01-04 19:17:03.269: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:17:03.269: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:17:03.270: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.271: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:643|FUNC:run] |   if (url != null) { |     if (file != null) { |         // 从本地缓存目录中获取图片文件成功,取得文件大小 |         fileSize=330853

01-04 19:17:03.271: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.325: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41ca7db8

01-04 19:17:03.325: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:17:03.326: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:17:03.326: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:17:03.336: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:17:03.337: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.338: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.338: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:17:03.339: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:17:03.341: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:523|FUNC:run] |   begin

01-04 19:17:03.343: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:533|FUNC:run] |   if (url != null) {

01-04 19:17:03.345: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:558|FUNC:run] |   if (url != null) { |     imageFilename=cb53fe67e5debda32b7bd80e8e05eec5.jpg |     strUrl=http://pic4.nipic.com/20091029/711581_150148008303_2.jpg

01-04 19:17:03.346: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:569|FUNC:run] |   if (url != null) { |     //锁定共享资源,查询要下载的图片是否已有别的线程正在下载 |     synchronized (downloadFilenamesSynchornizedLock) {

01-04 19:17:03.348: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:582|FUNC:run] |   if (url != null) { |     //查询要下载的图片是否已有别的线程正在下载,结果 |     downloading=false

01-04 19:17:03.350: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:620|FUNC:run] |   if (url != null) { |     //试图从本地缓存目录中获取图片文件,结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.352: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:643|FUNC:run] |   if (url != null) { |     if (file != null) { |         // 从本地缓存目录中获取图片文件成功,取得文件大小 |         fileSize=330853

01-04 19:17:03.353: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:819|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     file=/mnt/sdcard/com.zjg.youhuodong/image_cache/cb53fe67e5debda32b7bd80e8e05eec5.jpg

01-04 19:17:03.407: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@416e6a38

01-04 19:17:03.407: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:17:03.408: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:17:03.408: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:17:03.409: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:17:03.409: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.410: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.410: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:17:03.411: I/youhuodong(16110): Thread[pool-2-thread-1,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

01-04 19:17:03.502: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:890|FUNC:run] |   if (file != null) { |     // 从文件里按要求加载图片,并缓存,然后返回结果 |     bitmap=android.graphics.Bitmap@41844c20

01-04 19:17:03.502: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:903|FUNC:run] |   if (file != null) { |     if (bitmap != null) { |       // 加入到缓存 |       addBitmapToMemoryCache(strUrl, bitmap);

01-04 19:17:03.503: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:126|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) {

01-04 19:17:03.503: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:153|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中 |   synchronized (addingKeysSynchronizedLock) { |   adding = addingKeys.contains(key);

01-04 19:17:03.504: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:166|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 查询相同key对应的bitmap是否正在被其它线程添加到缓存中,结果 |   adding =false

01-04 19:17:03.505: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:206|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,添加key到正在加入到缓存的key集合 |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.506: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:223|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |       // 锁定共享资源,从正在加入到缓存的key集合除去key |       synchronized (addingKeysSynchronizedLock) {

01-04 19:17:03.507: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:236|FUNC:addBitmapToMemoryCache] | private static void addBitmapToMemoryCache(String key, Bitmap bitmap) { |   // 通知等待本线程添加相同key对应的bitmap到缓存的其他线程,唤醒它们以让它们继续执行 |   synchronized (addingKeysSynchronizedLock) { |     memoryCacheSynchronizedLock.notifyAll();

01-04 19:17:03.507: I/youhuodong(16110): Thread[pool-2-thread-2,5,main] | [FILE:BitmapCache.java|LINE:938|FUNC:run] |  end

 

 

 



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Android中的Picasso或Glide库来读取网络图片并将其转换为Bitmap,然后显示在控件上。 使用Picasso库的代码示例如下: ```java Picasso.get().load("http://example.com/image.jpg").into(new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { // 在这里处理Bitmap并显示在控件上 } @Override public void onBitmapFailed(Exception e, Drawable errorDrawable) { // 加载失败时的处理逻辑 } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { // 加载前的处理逻辑 } }); ``` 使用Glide库的代码示例如下: ```java Glide.with(context) .asBitmap() .load("http://example.com/image.jpg") .into(new SimpleTarget<Bitmap>() { @Override public void onResourceReady(Bitmap bitmap, Transition<? super Bitmap> transition) { // 在这里处理Bitmap并显示在控件上 } }); ``` ### 回答2: 在Android中,要读取网络图片并将其转换为Bitmap并显示在控件上,可以使用以下步骤: 1. 首先,你需要在AndroidManifest.xml文件中添加网络权限,以便应用能够访问网络: <uses-permission android:name="android.permission.INTERNET" /> 2. 在布局文件中,添加一个ImageView控件来显示网络图片: <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> 3. 在代码中,你可以使用异步任务AsyncTask来进行网络请求和图片加载操作。创建一个类继承AsyncTask,并在doInBackground方法中执行网络请求和图片加载的操作: private class LoadImageTask extends AsyncTask<String, Void, Bitmap> { @Override protected Bitmap doInBackground(String... urls) { String url = urls[0]; Bitmap bitmap = null; try { URL imageUrl = new URL(url); HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection(); conn.setConnectTimeout(30000); conn.setReadTimeout(30000); conn.setInstanceFollowRedirects(true); InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (Exception e) { e.printStackTrace(); } return bitmap; } @Override protected void onPostExecute(Bitmap result) { ImageView imageView = findViewById(R.id.imageView); imageView.setImageBitmap(result); } } 4. 在主活动中,创建LoadImageTask实例并执行execute方法,传入图片的URL: LoadImageTask task = new LoadImageTask(); task.execute("http://example.com/image.jpg"); 这样,网络图片会被下载并转换为Bitmap,然后在ImageView控件上显示出来。 需要注意的是,网络请求要在子线程中执行,不能在主线程中进行,否则会导致主线程阻塞。所以,我们使用了异步任务AsyncTask来实现这一功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值