public void finish(String paramString) {
   try {
     this.mFinished = true;
     long l1 = getTotalDuration();
     if (l1 <= 0L) ;
     while (true) {
       return;
       long l2 = ((Marker) this.mMarkers.get(0)).time;
       Object[] arrayOfObject1 = new Object[2];
       arrayOfObject1[0] = Long.valueOf(l1);
       arrayOfObject1[1] = paramString;
       VolleyLog.d("(%-4d ms) %s", arrayOfObject1);
       Iterator localIterator = this.mMarkers.iterator();
       while (localIterator.hasNext()) {
         Marker localMarker = (Marker) localIterator.next();
         long l3 = localMarker.time;
         Object[] arrayOfObject2 = new Object[3];
         arrayOfObject2[0] = Long.valueOf(l3 - l2);
         arrayOfObject2[1] = Long.valueOf(localMarker.thread);
         arrayOfObject2[2] = localMarker.name;
         VolleyLog.d("(+%-4d) [%2d] %s", arrayOfObject2);
         l2 = l3;
       }
     }
   } finally {
   }
 }
  /** Returns the cache entry with the specified key if it exists, null otherwise. */
  @Override
  public synchronized Entry get(String key) {
    CacheHeader entry = mEntries.get(key); // 获取摘要
    // if the entry does not exist, return.
    if (entry == null) {
      return null;
    }

    File file = getFileForKey(key); // 获取文件
    CountingInputStream cis = null;
    try {
      cis = new CountingInputStream(new FileInputStream(file));
      CacheHeader.readHeader(cis); // eat header文件的具体内容在摘要之后,所有先读取摘要,将当前读取位置移动到摘要之后
      byte[] data = streamToBytes(cis, (int) (file.length() - cis.bytesRead)); // 当前位置移动到摘要之后,读取缓存内容
      return entry.toCacheEntry(data); // 根据读取的缓存内容,结合缓存摘要,生成Cache.Entry对象
    } catch (IOException e) {
      VolleyLog.d("%s: %s", file.getAbsolutePath(), e.toString());
      remove(key); // 发生异常则删除异常缓存
      return null;
    } finally {
      if (cis != null) {
        try {
          cis.close();
        } catch (IOException ioe) {
          return null;
        }
      }
    }
  }
  /**
   * Initializes the DiskBasedCache by scanning for all files currently in the specified root
   * directory. Creates the root directory if necessary.
   */
  @Override
  public synchronized void initialize() {
    if (!mRootDirectory.exists()) { // 如果根目录不存在,创建根目录
      if (!mRootDirectory.mkdirs()) {
        VolleyLog.e("Unable to create cache dir %s", mRootDirectory.getAbsolutePath());
      }
      return;
    }

    File[] files = mRootDirectory.listFiles();
    if (files == null) {
      return;
    }
    // 遍历所有的文件,将文件转换为CacheHeader对象,并将其添加到缓存集合之中
    for (File file : files) {
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(file);
        CacheHeader entry = CacheHeader.readHeader(fis);
        entry.size = file.length();
        putEntry(entry.key, entry);
      } catch (IOException e) {
        if (file != null) {
          file.delete(); // 如果存在异常则删除异常文件
        }
      } finally {
        try {
          if (fis != null) {
            fis.close();
          }
        } catch (IOException ignored) {
        }
      }
    }
  }
 /** Reads the contents of HttpEntity into a byte[]. */
 private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError {
   PoolingByteArrayOutputStream bytes =
       new PoolingByteArrayOutputStream(mPool, (int) entity.getContentLength());
   byte[] buffer = null;
   try {
     InputStream in = entity.getContent();
     if (in == null) {
       throw new ServerError();
     }
     buffer = mPool.getBuf(1024);
     int count;
     while ((count = in.read(buffer)) != -1) {
       bytes.write(buffer, 0, count);
     }
     return bytes.toByteArray();
   } finally {
     try {
       // Close the InputStream and release the resources by "consuming the content".
       entity.consumeContent();
     } catch (IOException e) {
       // This can happen if there was an exception above that left the entity in
       // an invalid state.
       VolleyLog.v("Error occured when calling consumingContent");
     }
     mPool.returnBuf(buffer);
     bytes.close();
   }
 }
  /**
   * Called from {@link Request#finish(String)}, indicating that processing of the given request has
   * finished.
   *
   * <p>Releases waiting requests for <code>request.getCacheKey()</code> if <code>
   * request.shouldCache()</code>.
   *
   * <p>(1). 首先从正在进行中请求集合mCurrentRequests中移除该请求。 (2).
   * 然后查找请求等待集合mWaitingRequests中是否存在等待的请求,如果存在,则将等待队列移除,
   * 并将等待队列所有的请求添加到缓存请求队列中,让缓存请求处理线程CacheDispatcher自动处理。
   */
  <T> void finish(Request<T> request) {
    // Remove from the set of requests currently being processed.
    synchronized (mCurrentRequests) {
      mCurrentRequests.remove(request);
    }
    synchronized (mFinishedListeners) {
      for (RequestFinishedListener<T> listener : mFinishedListeners) {
        listener.onRequestFinished(request);
      }
    }

    if (request.shouldCache()) {
      synchronized (mWaitingRequests) {
        String cacheKey = request.getCacheKey();
        Queue<Request<?>> waitingRequests = mWaitingRequests.remove(cacheKey);
        if (waitingRequests != null) {
          if (VolleyLog.DEBUG) {
            VolleyLog.v(
                "Releasing %d waiting requests for cacheKey=%s.", waitingRequests.size(), cacheKey);
          }
          // Process all queued up requests. They won't be considered as in flight, but
          // that's not a problem as the cache has been primed by 'request'.
          mCacheQueue.addAll(waitingRequests);
        }
      }
    }
  }
Exemple #6
0
  /**
   * Notifies the request queue that this request has finished (successfully or with error).
   *
   * <p>Also dumps all events from this request's event log; for debugging.
   */
  void finish(final String tag) {
    if (mRequestQueue != null) {
      mRequestQueue.finish(this);
    }
    if (MarkerLog.ENABLED) {
      final long threadId = Thread.currentThread().getId();
      if (Looper.myLooper() != Looper.getMainLooper()) {
        // If we finish marking off of the main thread, we need to
        // actually do it on the main thread to ensure correct ordering.
        Handler mainThread = new Handler(Looper.getMainLooper());
        mainThread.post(
            new Runnable() {
              @Override
              public void run() {
                mEventLog.add(tag, threadId);
                mEventLog.finish(this.toString());
              }
            });
        return;
      }

      mEventLog.add(tag, threadId);
      mEventLog.finish(this.toString());
    } else {
      long requestTime = SystemClock.elapsedRealtime() - mRequestBirthTime;
      if (requestTime >= SLOW_REQUEST_THRESHOLD_MS) {
        VolleyLog.d("%d ms: %s", requestTime, this.toString());
      }
    }
  }
 public static void setupVolleyQueue() {
   requestQueue = Volley.newRequestQueue(mContext, VolleyUtils.getHTTPClientStack(mContext));
   imageLoader = new ImageLoader(requestQueue, getBitmapCache());
   VolleyLog.setTag(AppLog.TAG);
   // http://stackoverflow.com/a/17035814
   imageLoader.setBatchedResponseDelay(0);
 }
 /** Reads the contents of HttpEntity into a byte[]. */
 private byte[] entityToBytes(HttpResponse httpResponse) throws IOException, ServerError {
   //    private byte[] entityToBytes(HttpEntity entity) throws IOException, ServerError {
   HttpEntity entity = httpResponse.getEntity();
   PoolingByteArrayOutputStream bytes =
       new PoolingByteArrayOutputStream(mPool, (int) entity.getContentLength());
   byte[] buffer = null;
   try {
     //            InputStream in = entity.getContent();
     Header contentEncoding = httpResponse.getFirstHeader("Content-Encoding");
     InputStream in = entity.getContent();
     if (contentEncoding != null && contentEncoding.getValue().equalsIgnoreCase("gzip")) {
       in = new GZIPInputStream(in);
     }
     if (in == null) {
       throw new ServerError();
     }
     buffer = mPool.getBuf(1024);
     int count;
     while ((count = in.read(buffer)) != -1) {
       bytes.write(buffer, 0, count);
     }
     return bytes.toByteArray();
   } finally {
     try {
       // Close the InputStream and release the resources by "consuming the content".
       entity.consumeContent();
     } catch (IOException e) {
       // This can happen if there was an exception above that left the entity in
       // an invalid state.
       VolleyLog.v("Error occured when calling consumingContent");
     }
     mPool.returnBuf(buffer);
     bytes.close();
   }
 }
 private void buildMultipartEntity() {
   entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
   try {
     entity.addPart(STRING_PART_NAME, new StringBody(mStringPart));
   } catch (UnsupportedEncodingException e) {
     VolleyLog.e("UnsupportedEncodingException");
   }
 }
  public <T> void addToRequestQueue(Request<T> req, String tag) {
    // set the default tag if tag is empty
    req.setTag(TextUtils.isEmpty(tag) ? "TAG" : tag);

    VolleyLog.d("Adding request to queue: %s", req.getUrl());

    getRequestQueue().add(req);
  }
Exemple #11
0
 protected void finalize() throws Throwable {
   if (!this.mFinished) {
     finish("Request on the loose");
     VolleyLog.e(
         "Marker log finalized without finish() - uncaught exit point for request",
         new Object[0]);
   }
 }
  /**
   * Prunes the cache to fit the amount of bytes specified.
   *
   * @param neededSpace The amount of bytes we are trying to fit into the cache.
   */
  private void pruneIfNeeded(int neededSpace) {
    if ((mTotalSize + neededSpace) < mMaxCacheSizeInBytes) {
      // 未超过缓存最大值限制,直接返回
      return;
    }
    if (VolleyLog.DEBUG) {
      VolleyLog.v("Pruning old cache entries.");
    }

    long before = mTotalSize;
    int prunedFiles = 0;
    long startTime = SystemClock.elapsedRealtime();

    Iterator<Map.Entry<String, CacheHeader>> iterator = mEntries.entrySet().iterator();
    // 遍历缓存集合
    while (iterator.hasNext()) {
      Map.Entry<String, CacheHeader> entry = iterator.next();
      // 删除缓存集合头部CacheHeader对象对应的缓存文件,
      CacheHeader e = entry.getValue();
      boolean deleted = getFileForKey(e.key).delete();
      if (deleted) {
        mTotalSize -= e.size; // 删除头部元素后当前缓存的大小
      } else {
        VolleyLog.d(
            "Could not delete cache entry for key=%s, filename=%s",
            e.key, getFilenameForKey(e.key));
      }
      iterator.remove(); // 删除缓存集合头部CacheHeader对象
      prunedFiles++;

      if ((mTotalSize + neededSpace) < mMaxCacheSizeInBytes * HYSTERESIS_FACTOR) {
        // mTotalSize:当前缓存的大小
        // neededSpace:即将添加到缓存文件之中原始响应内容的大小
        // mMaxCacheSizeInBytes:缓存最大值限制
        // HYSTERESIS_FACTOR:缓存最高水准线(mMaxCacheSizeInBytes的百分之多少,其默认值为0.9)
        break;
      }
    }

    if (VolleyLog.DEBUG) {
      VolleyLog.v(
          "pruned %d files, %d bytes, %d ms",
          prunedFiles, (mTotalSize - before), SystemClock.elapsedRealtime() - startTime);
    }
  }
 /** Removes the specified key from the cache if it exists. */
 @Override
 public synchronized void remove(String key) {
   boolean deleted = getFileForKey(key).delete();
   removeEntry(key);
   if (!deleted) {
     VolleyLog.d(
         "Could not delete cache entry for key=%s, filename=%s", key, getFilenameForKey(key));
   }
 }
 @Override
 public byte[] getBody() throws AuthFailureError {
   ByteArrayOutputStream bos = new ByteArrayOutputStream();
   try {
     entity.writeTo(bos);
   } catch (IOException e) {
     VolleyLog.e("IOException writing to ByteArrayOutputStream");
   }
   return bos.toByteArray();
 }
 public byte[] getBody() {
   try {
     return this.mRequestBody == null ? null : this.mRequestBody.getBytes("utf-8");
   } catch (UnsupportedEncodingException var2) {
     VolleyLog.wtf(
         "Unsupported Encoding while trying to get the bytes of %s using %s",
         new Object[] {this.mRequestBody, "utf-8"});
     return null;
   }
 }
  /** Loads the image for the view if it isn't already loaded. */
  private void loadImageIfNecessary() {
    int width = getWidth();
    int height = getHeight();

    // if the view's bounds aren't known yet, hold off on loading the image.
    if (width == 0 && height == 0) {
      return;
    }

    // if the URL to be loaded in this view is empty, cancel any old requests and clear the
    // currently loaded image.
    if (TextUtils.isEmpty(mUrl)) {
      if (mImageContainer != null) {
        mImageContainer.cancelRequest();
        mImageContainer = null;
      }
      setImageBitmap(null);
      VolleyLog.d(TAG, "Not loading image");
      return;
    }

    // if there was an old request in this view, check if it needs to be canceled.
    if (mImageContainer != null && mImageContainer.getRequestUrl() != null) {
      if (mImageContainer.getRequestUrl().equals(mUrl)) {
        // if the request is from the same URL, return.
        return;
      } else {
        // if there is a pre-existing request, cancel it if it's fetching a different URL.
        mImageContainer.cancelRequest();
        setImageBitmap(null);
      }
    }

    // The pre-existing content of this view didn't match the current URL. Load the new image
    // from the network.
    VolleyLog.d(TAG, "Start loading image");
    ImageContainer newContainer =
        mImageLoader.get(mUrl, ImageLoader.getImageListener(this, mDefaultImageId, mErrorImageId));

    // update the ImageContainer to be the new bitmap container.
    mImageContainer = newContainer;
  }
Exemple #17
0
 @Override
 public byte[] getBody() {
   try {
     return mRequestBody == null ? null : mRequestBody.getBytes(PROTOCOL_CHARSET);
   } catch (UnsupportedEncodingException uee) {
     VolleyLog.wtf(
         "Unsupported Encoding while trying to get the bytes of %s using %s",
         mRequestBody, PROTOCOL_CHARSET);
     return null;
   }
 }
 /** Logs requests that took over SLOW_REQUEST_THRESHOLD_MS to complete. */
 private void logSlowRequests(
     long requestLifetime, Request<?> request, byte[] responseContents, StatusLine statusLine) {
   if (DEBUG || requestLifetime > SLOW_REQUEST_THRESHOLD_MS) {
     VolleyLog.d(
         "HTTP response for request=<%s> [lifetime=%d], [size=%s], " + "[rc=%d], [retryCount=%s]",
         request,
         requestLifetime,
         responseContents != null ? responseContents.length : "null",
         statusLine.getStatusCode(),
         request.getRetryPolicy().getCurrentRetryCount());
   }
 }
 /** Clears the cache. Deletes all cached files from disk. */
 @Override
 public synchronized void clear() {
   File[] files = mRootDirectory.listFiles();
   if (files != null) {
     for (File file : files) {
       file.delete();
     }
   }
   mEntries.clear();
   mTotalSize = 0;
   VolleyLog.d("Cache cleared.");
 }
  @Override
  public byte[] getBody() throws AuthFailureError {
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
      entity.writeTo(bos);
    } catch (IOException e) {
      VolleyLog.e("IOException writing to ByteArrayOutputStream");
    }

    //   return bos.toByteArray();
    System.out.println("write entity:" + byteArrayGlobal.toString());
    return byteArrayGlobal;
  }
 /**
  * Cancels all requests in this queue with the given tag. Tag must be non-null and equality is by
  * identity.
  */
 public void cancelAll(final Object tag) {
   if (tag == null) {
     throw new IllegalArgumentException("Cannot cancelAll with a null tag");
   }
   VolleyLog.v("Cancel Requests for Tag %s", tag.toString());
   cancelAll(
       new RequestFilter() {
         @Override
         public boolean apply(Request<?> request) {
           return request.getTag() == tag;
         }
       });
 }
 private void buildMultipartEntity() {
   entity.addPart(
       "profile_picture",
       new FileBody(new File("/storage/emulated/0/Pictures/VSCOCam/2015-07-31 11.55.14 1.jpg")));
   try {
     entity.addPart("user_id", new StringBody("15"));
     entity.addPart("name", new StringBody("Bogs"));
     entity.addPart("gender", new StringBody("Male"));
     entity.addPart("date_birth", new StringBody("1999-12-5"));
     entity.addPart("breed", new StringBody("monkey"));
   } catch (UnsupportedEncodingException e) {
     VolleyLog.e("UnsupportedEncodingException");
   }
 }
 public byte[] getBody() {
   if (mRequestBody == null) {
     return null;
   }
   byte abyte0[];
   try {
     abyte0 = mRequestBody.getBytes("utf-8");
   } catch (UnsupportedEncodingException unsupportedencodingexception) {
     VolleyLog.wtf(
         "Unsupported Encoding while trying to get the bytes of %s using %s",
         new Object[] {mRequestBody, "utf-8"});
     return null;
   }
   return abyte0;
 }
 /** Writes the contents of this CacheHeader to the specified OutputStream. CacheHeader转换成文件 */
 public boolean writeHeader(OutputStream os) {
   try {
     writeInt(os, CACHE_MAGIC);
     writeString(os, key);
     writeString(os, etag == null ? "" : etag);
     writeLong(os, serverDate);
     writeLong(os, ttl);
     writeLong(os, softTtl);
     writeStringStringMap(responseHeaders, os);
     os.flush();
     return true;
   } catch (IOException e) {
     VolleyLog.d("%s", e.toString());
     return false;
   }
 }
  /**
   * Adds a Request to the dispatch queue.
   *
   * @param request The request to service
   * @return The passed-in request
   */
  public Request add(Request request) {
    // Tag the request as belonging to this queue and add it to the set of current requests.
    request.setRequestQueue(this);

    // Rewrite the url, in case of GET requests
    if (mUrlRewriter != null) {
      request.setUrl(mUrlRewriter.rewriteUrl(request));
    }

    synchronized (mCurrentRequests) {
      mCurrentRequests.add(request);
    }

    // Process requests in the order they are added.
    request.setSequence(getSequenceNumber());
    request.addMarker("add-to-queue");

    // If the request is uncacheable, skip the cache queue and go straight to the network.
    if (!request.shouldCache()) {
      mNetworkQueue.add(request);
      return request;
    }

    // Insert request into stage if there's already a request with the same cache key in flight.
    synchronized (mWaitingRequests) {
      String cacheKey = request.getCacheKey();
      if (mWaitingRequests.containsKey(cacheKey)) {
        // There is already a request in flight. Queue up.
        Queue<Request> stagedRequests = mWaitingRequests.get(cacheKey);
        if (stagedRequests == null) {
          stagedRequests = new LinkedList<Request>();
        }
        stagedRequests.add(request);
        mWaitingRequests.put(cacheKey, stagedRequests);
        if (VolleyLog.sDebug) {
          VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);
        }
      } else {
        // Insert 'null' queue for this cacheKey, indicating there is now a request in
        // flight.
        mWaitingRequests.put(cacheKey, null);
        mCacheQueue.add(request);
      }
      return request;
    }
  }
 /** Puts the entry with the specified key into the cache. */
 @Override
 public synchronized void put(String key, Entry entry) {
   pruneIfNeeded(entry.data.length);
   File file = getFileForKey(key); // 根据key找到缓存文件
   try {
     FileOutputStream fos = new FileOutputStream(file);
     CacheHeader e = new CacheHeader(key, entry); // 通过Cache.Entry生成一个摘要(CacheHeader)
     e.writeHeader(fos); // 将摘要写入缓存文件之中
     fos.write(entry.data); // 将内容写入缓存文件之中
     fos.close();
     putEntry(key, e); // 将摘要添加到缓存集合之中
     return;
   } catch (IOException e) {
   }
   boolean deleted = file.delete();
   if (!deleted) {
     VolleyLog.d("Could not clean up file %s", file.getAbsolutePath());
   }
 }
  public MultipartRequest(
      String url,
      Response.Listener<String> rListener,
      Response.ErrorListener eListener,
      @Nullable HashMap<String, String> head,
      @NonNull String stringPart,
      @NonNull File file,
      @Nullable Map<String, Object> param) {
    super(Method.POST, url, rListener, eListener);

    header = null;
    if (head == null) {
      header = new HashMap<>();
    } else {
      header = (HashMap) head.clone();
    }

    String boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW";
    header.put("Content-Type", "multipart/form-data; boundary=" + boundary);

    // build multi-part
    MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
    entityBuilder.setBoundary(boundary);
    entityBuilder.addPart(stringPart, new FileBody(file));
    if (param != null) {
      try {
        for (String key : param.keySet()) {
          Object obj = param.get(key);
          String input = obj.toString();
          entityBuilder.addPart(key, new StringBody(input, ContentType.MULTIPART_FORM_DATA));
        }
      } catch (Exception e) {
        VolleyLog.e("Fail to build multipart. " + e.getMessage());
        e.printStackTrace();
      }
    }
    entity = entityBuilder.build();
  }
Exemple #28
0
  private static void addColumns2Map(
      Class<?> entityType, String primaryKeyFieldName, HashMap<String, Column> columnMap) {
    if (Object.class.equals(entityType)) return;
    try {
      Field[] fields = entityType.getDeclaredFields();
      for (Field field : fields) {
        if (ColumnUtils.isTransient(field) || Modifier.isStatic(field.getModifiers())) {
          continue;
        }
        if (ColumnConverterFactory.isSupportColumnConverter(field.getType())) {
          if (!field.getName().equals(primaryKeyFieldName)) {
            Column column = new Column(entityType, field);
            if (!columnMap.containsKey(column.getColumnName())) {
              columnMap.put(column.getColumnName(), column);
            }
          }
        } else if (ColumnUtils.isForeign(field)) {
          Foreign column = new Foreign(entityType, field);
          if (!columnMap.containsKey(column.getColumnName())) {
            columnMap.put(column.getColumnName(), column);
          }
        } else if (ColumnUtils.isFinder(field)) {
          Finder column = new Finder(entityType, field);
          if (!columnMap.containsKey(column.getColumnName())) {
            columnMap.put(column.getColumnName(), column);
          }
        }
      }

      if (!Object.class.equals(entityType.getSuperclass())) {
        addColumns2Map(entityType.getSuperclass(), primaryKeyFieldName, columnMap);
      }
    } catch (Throwable e) {
      VolleyLog.e(e.getMessage(), e);
    }
  }
  @Override
  public void run() {
    if (DEBUG) {
      VolleyLog.v("start new dispatcher");
    }
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
    // Make a blocking call to initialize the cache.
    mCache.initialize();
    while (true) {
      try {
        // Get a request from the cache triage queue, blocking until at least one is available.
        final Request<?> request = mCacheQueue.take();
        request.addMarker("cache-queue-take");
        // If the request has been canceled, don't bother dispatching it.
        if (request.isCanceled()) {
          request.finish("cache-discard-canceled");
          continue;
        }

        // Attempt to retrieve this item from cache.
        Cache.Entry entry = mCache.get(request.getCacheKey());
        if (entry == null) {
          request.addMarker("cache-miss");
          // Cache miss; send off to the network dispatcher.
          mNetworkQueue.put(request);
          continue;
        }

        // If it is completely expired, just send it to the network.
        if (entry.isExpired()) {
          request.addMarker("cache-hit-expired");
          request.setCacheEntry(entry);
          mNetworkQueue.put(request);
          continue;
        }

        // We have a cache hit; parse its data for delivery back to the request.
        request.addMarker("cache-hit");
        Response<?> response =
            request.parseNetworkResponse(
                new NetworkResponse(entry.data, entry.responseHeaders)); // TODO
        request.addMarker("cache-hit-parsed");

        if (!entry.refreshNeeded()) {
          // Completely unexpired cache hit. Just deliver the response.
          mDelivery.postResponse(request, response);
        } else {
          // Soft-expired cache hit. We can deliver the cached response,
          // but we need to also send the request to the network for
          // refreshing.
          request.addMarker("cache-hit-refresh-needed");
          request.setCacheEntry(entry);

          // Mark the response as intermediate.
          response.intermediate = true;

          // Post the intermediate response back to the user and have
          // the delivery then forward the request along to the network.
          mDelivery.postResponse(
              request,
              response,
              new Runnable() {
                @Override
                public void run() {
                  try {
                    mNetworkQueue.put(request);
                  } catch (InterruptedException e) {
                    // Not much we can do about this.
                  }
                }
              });
        }

      } catch (InterruptedException e) {
        // We may have been interrupted because it was time to quit.
        if (mQuit) {
          return;
        }
        continue;
      }
    }
  }
 protected void logError(String what, String url, long start) {
   long now = SystemClock.elapsedRealtime();
   VolleyLog.v("HTTP ERROR(%s) %d ms to fetch %s", what, (now - start), url);
 }