/** This is a functor class of type Runnable. The run method is the encapsulated function. */
    @Override
    public void run() {

      onTileLoaderInit();

      MapTileRequestState state;
      Drawable result = null;
      while ((state = nextTile()) != null) {
        if (DEBUG_TILE_PROVIDERS) {
          logger.debug("TileLoader.run() processing next tile: " + state.getMapTile());
        }
        try {
          result = null;
          result = loadTile(state);
        } catch (final CantContinueException e) {
          logger.info("Tile loader can't continue: " + state.getMapTile(), e);
          clearQueue();
        } catch (final Throwable e) {
          logger.error("Error downloading tile: " + state.getMapTile(), e);
        }

        if (result == null) {
          tileLoadedFailed(state);
        } else if (ExpirableBitmapDrawable.isDrawableExpired(result)) {
          tileLoadedExpired(state, result);
        } else {
          tileLoaded(state, result);
        }
      }

      onTileLoaderShutdown();
    }
  public void loadMapTileAsync(final MapTileRequestState pState) {
    synchronized (mQueueLockObject) {
      if (DEBUG_TILE_PROVIDERS) {
        logger.debug(
            "MapTileModuleProviderBase.loadMaptileAsync() on provider: "
                + getName()
                + " for tile: "
                + pState.getMapTile());
        if (mPending.containsKey(pState.getMapTile()))
          logger.debug(
              "MapTileModuleProviderBase.loadMaptileAsync() tile already exists in request queue for modular provider. Moving to front of queue.");
        else
          logger.debug(
              "MapTileModuleProviderBase.loadMaptileAsync() adding tile to request queue for modular provider.");
      }

      // this will put the tile in the queue, or move it to the front of
      // the queue if it's already present
      mPending.put(pState.getMapTile(), pState);
    }
    try {
      mExecutor.execute(getTileLoader());
    } catch (final RejectedExecutionException e) {
      logger.warn("RejectedExecutionException", e);
    }
  }
 protected void tileLoadedFailed(final MapTileRequestState pState) {
   if (DEBUG_TILE_PROVIDERS) {
     logger.debug(
         "TileLoader.tileLoadedFailed() on provider: "
             + getName()
             + " with tile: "
             + pState.getMapTile());
   }
   removeTileFromQueues(pState.getMapTile());
   pState.getCallback().mapTileRequestFailed(pState);
 }