@Override
 protected void onDialogClosed(boolean positiveResult) {
   if (positiveResult) {
     CPDecksDBHelper.clearCachedApiData();
     UrlImageViewHelper.cleanup(mContext, 1);
   }
   super.onDialogClosed(positiveResult);
 }
  private static void setUrlDrawable(
      final Context context,
      ImageView imageView,
      final String url,
      final Drawable defaultDrawable,
      long cacheDurationMs,
      final UrlImageViewCallback callback) {
    cleanup(context);
    // disassociate this ImageView from any pending downloads
    if (isNullOrEmpty(url)) {
      if (imageView != null) imageView.setImageDrawable(defaultDrawable);
      return;
    }

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();
    int tw = display.getWidth();
    int th = display.getHeight();

    if (mDeadCache == null) mDeadCache = new UrlLruCache(getHeapSize(context) / 8);
    Drawable drawable;
    BitmapDrawable zd = mDeadCache.remove(url);
    if (zd != null) {
      // this drawable was resurrected, it should not be in the live cache
      if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "zombie load");
      Assert.assertTrue(!mAllCache.contains(zd));
      drawable = new ZombieDrawable(url, zd);
    } else {
      drawable = mLiveCache.get(url);
    }

    if (drawable != null) {
      if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "Cache hit on: " + url);
      if (imageView != null) imageView.setImageDrawable(drawable);
      if (callback != null) callback.onLoaded(imageView, drawable, url, true);
      return;
    }

    // oh noes, at this point we definitely do not have the file available in memory
    // let's prepare for an asynchronous load of the image.

    final String filename = context.getFileStreamPath(getFilenameForUrl(url)).getAbsolutePath();

    // null it while it is downloading
    if (imageView != null) imageView.setImageDrawable(defaultDrawable);

    // since listviews reuse their views, we need to
    // take note of which url this view is waiting for.
    // This may change rapidly as the list scrolls or is filtered, etc.
    if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "Waiting for " + url);
    if (imageView != null) mPendingViews.put(imageView, url);

    ArrayList<ImageView> currentDownload = mPendingDownloads.get(url);
    if (currentDownload != null) {
      // Also, multiple vies may be waiting for this url.
      // So, let's maintain a list of these views.
      // When the url is downloaded, it sets the imagedrawable for
      // every view in the list. It needs to also validate that
      // the imageview is still waiting for this url.
      if (imageView != null) currentDownload.add(imageView);
      return;
    }

    final ArrayList<ImageView> downloads = new ArrayList<ImageView>();
    if (imageView != null) downloads.add(imageView);
    mPendingDownloads.put(url, downloads);

    final int targetWidth = tw <= 0 ? Integer.MAX_VALUE : tw;
    final int targetHeight = th <= 0 ? Integer.MAX_VALUE : th;
    final Loader loader =
        new Loader() {
          @Override
          public void run() {
            try {
              result = loadDrawableFromStream(context, url, filename, targetWidth, targetHeight);
            } catch (Exception ex) {
            }
          }
        };

    final Runnable completion =
        new Runnable() {
          @Override
          public void run() {
            Assert.assertEquals(Looper.myLooper(), Looper.getMainLooper());
            Drawable usableResult = loader.result;
            if (usableResult == null) usableResult = defaultDrawable;
            mPendingDownloads.remove(url);
            mLiveCache.put(url, usableResult);
            for (ImageView iv : downloads) {
              // validate the url it is waiting for
              String pendingUrl = mPendingViews.get(iv);
              if (!url.equals(pendingUrl)) {
                if (Constants.LOG_ENABLED)
                  Log.i(Constants.LOGTAG, "Ignoring out of date request to update view for " + url);
                continue;
              }
              mPendingViews.remove(iv);
              if (usableResult != null) {
                //                        System.out.println(String.format("imageView: %dx%d,
                // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(),
                // imageView.getWidth(), imageView.getHeight()));
                iv.setImageDrawable(usableResult);
                //                        System.out.println(String.format("imageView: %dx%d,
                // %dx%d", imageView.getMeasuredWidth(), imageView.getMeasuredHeight(),
                // imageView.getWidth(), imageView.getHeight()));
                if (callback != null) callback.onLoaded(iv, loader.result, url, false);
              }
            }
          }
        };

    File file = new File(filename);
    if (file.exists()) {
      try {
        if (cacheDurationMs == CACHE_DURATION_INFINITE
            || System.currentTimeMillis() < file.lastModified() + cacheDurationMs) {
          if (Constants.LOG_ENABLED)
            Log.i(
                Constants.LOGTAG,
                "File Cache hit on: "
                    + url
                    + ". "
                    + (System.currentTimeMillis() - file.lastModified())
                    + "ms old.");

          AsyncTask<Void, Void, Void> fileloader =
              new AsyncTask<Void, Void, Void>() {
                protected Void doInBackground(Void[] params) {
                  loader.run();
                  return null;
                }

                protected void onPostExecute(Void result) {
                  completion.run();
                }
              };
          executeTask(fileloader);
          return;
        } else {
          if (Constants.LOG_ENABLED) Log.i(Constants.LOGTAG, "File cache has expired. Refreshing.");
        }
      } catch (Exception ex) {
      }
    }

    mDownloader.download(context, url, filename, loader, completion);
  }