code: public static void downloadAsync(ImageRequest request) {
          if (request == null) {
              return;
          }
  
          // NOTE: This is the ONLY place where the original request's Url is read. From here on,
          // we will keep track of the Url separately. This is because we might be dealing with a
          // redirect response and the Url might change. We can't create our own new ImageRequests
          // for these changed Urls since the caller might be doing some book-keeping with the request's
          // object reference. So we keep the old references and just map them to new urls in the downloader
          RequestKey key = new RequestKey(request.getImageUri(), request.getCallerTag());
          synchronized (pendingRequests) {
              DownloaderContext downloaderContext = pendingRequests.get(key);
              if (downloaderContext != null) {
                  downloaderContext.request = request;
                  downloaderContext.isCancelled = false;
                  downloaderContext.workItem.moveToFront();
              } else {
                  enqueueCacheRead(request, key, request.isCachedRedirectAllowed());
              }
          }
      }
docs: Downloads the image specified in the passed in request.
  If a callback is specified, it is guaranteed to be invoked on the calling thread.
  @param request Request to process