private void sendImageRequest(boolean allowCachedResponse) { try { ImageRequest.Builder requestBuilder = new ImageRequest.Builder( getContext(), ImageRequest.getProfilePictureUri(profileId, queryWidth, queryHeight)); ImageRequest request = requestBuilder .setAllowCachedRedirects(allowCachedResponse) .setCallerTag(this) .setCallback( new ImageRequest.Callback() { @Override public void onCompleted(ImageResponse response) { processResponse(response); } }) .build(); // Make sure to cancel the old request before sending the new one to prevent // accidental cancellation of the new request. This could happen if the URL and // caller tag stayed the same. if (lastRequest != null) { ImageDownloader.cancelRequest(lastRequest); } lastRequest = request; ImageDownloader.downloadAsync(request); } catch (Exception e) { Logger.log(LoggingBehavior.REQUESTS, Log.ERROR, TAG, e.toString()); } }
public void prioritizeViewRange(int firstVisibleItem, int lastVisibleItem, int prefetchBuffer) { if ((lastVisibleItem < firstVisibleItem) || (sectionKeys.size() == 0)) { return; } // We want to prioritize requests for items which are visible but do not have pictures // loaded yet. We also want to pre-fetch pictures for items which are not yet visible // but are within a buffer on either side of the visible items, on the assumption that // they will be visible soon. For these latter items, we'll store the images in memory // in the hopes we can immediately populate their image view when needed. // Prioritize the requests in reverse order since each call to prioritizeRequest will just // move it to the front of the queue. And we want the earliest ones in the range to be at // the front of the queue, so all else being equal, the list will appear to populate from // the top down. for (int i = lastVisibleItem; i >= 0; i--) { SectionAndItem<T> sectionAndItem = getSectionAndItem(i); if (sectionAndItem.graphObject != null) { String id = getIdOfGraphObject(sectionAndItem.graphObject); ImageRequest request = pendingRequests.get(id); if (request != null) { ImageDownloader.prioritizeRequest(request); } } } // For items which are not visible, but within the buffer on either side, we want to // fetch those items and store them in a small in-memory cache of bitmaps. int start = Math.max(0, firstVisibleItem - prefetchBuffer); int end = Math.min(lastVisibleItem + prefetchBuffer, getCount() - 1); ArrayList<T> graphObjectsToPrefetchPicturesFor = new ArrayList<T>(); // Add the IDs before and after the visible range. for (int i = start; i < firstVisibleItem; ++i) { SectionAndItem<T> sectionAndItem = getSectionAndItem(i); if (sectionAndItem.graphObject != null) { graphObjectsToPrefetchPicturesFor.add(sectionAndItem.graphObject); } } for (int i = lastVisibleItem + 1; i <= end; ++i) { SectionAndItem<T> sectionAndItem = getSectionAndItem(i); if (sectionAndItem.graphObject != null) { graphObjectsToPrefetchPicturesFor.add(sectionAndItem.graphObject); } } for (T graphObject : graphObjectsToPrefetchPicturesFor) { URI uri = getPictureUriOfGraphObject(graphObject); final String id = getIdOfGraphObject(graphObject); // This URL already have been requested for pre-fetching, but we want to act in an LRU manner, // so move // it to the end of the list regardless. boolean alreadyPrefetching = prefetchedProfilePictureIds.remove(id); prefetchedProfilePictureIds.add(id); // If we've already requested it for pre-fetching, no need to do so again. if (!alreadyPrefetching) { downloadProfilePicture(id, uri, null); } } }
private void updateUI() { if (!isAdded()) { return; } if (isSessionOpen()) { connectedStateLabel.setTextColor( getResources().getColor(R.color.com_facebook_usersettingsfragment_connected_text_color)); connectedStateLabel.setShadowLayer( 1f, 0f, -1f, getResources() .getColor(R.color.com_facebook_usersettingsfragment_connected_shadow_color)); if (user != null) { ImageRequest request = getImageRequest(); if (request != null) { URI requestUrl = request.getImageUri(); // Do we already have the right picture? If so, leave it alone. if (!requestUrl.equals(connectedStateLabel.getTag())) { if (user.getId().equals(userProfilePicID)) { connectedStateLabel.setCompoundDrawables(null, userProfilePic, null, null); connectedStateLabel.setTag(requestUrl); } else { ImageDownloader.downloadAsync(request); } } } connectedStateLabel.setText(user.getName()); } else { connectedStateLabel.setText( getResources().getString(R.string.com_facebook_usersettingsfragment_logged_in)); Drawable noProfilePic = getResources().getDrawable(R.drawable.com_facebook_profile_default_icon); noProfilePic.setBounds( 0, 0, getResources() .getDimensionPixelSize( R.dimen.com_facebook_usersettingsfragment_profile_picture_width), getResources() .getDimensionPixelSize( R.dimen.com_facebook_usersettingsfragment_profile_picture_height)); connectedStateLabel.setCompoundDrawables(null, noProfilePic, null, null); } } else { int textColor = getResources() .getColor(R.color.com_facebook_usersettingsfragment_not_connected_text_color); connectedStateLabel.setTextColor(textColor); connectedStateLabel.setShadowLayer(0f, 0f, 0f, textColor); connectedStateLabel.setText( getResources().getString(R.string.com_facebook_usersettingsfragment_not_logged_in)); connectedStateLabel.setCompoundDrawables(null, null, null, null); connectedStateLabel.setTag(null); } }
private void downloadProfilePicture( final String profileId, URI pictureURI, final ImageView imageView) { if (pictureURI == null) { return; } // If we don't have an imageView, we are pre-fetching this image to store in-memory because we // think the user might scroll to its corresponding list row. If we do have an imageView, we // only want to queue a download if the view's tag isn't already set to the URL (which would // mean // it's already got the correct picture). boolean prefetching = imageView == null; if (prefetching || !pictureURI.equals(imageView.getTag())) { if (!prefetching) { // Setting the tag to the profile ID indicates that we're currently downloading the // picture for this profile; we'll set it to the actual picture URL when complete. imageView.setTag(profileId); imageView.setImageResource(getDefaultPicture()); } ImageRequest.Builder builder = new ImageRequest.Builder(context.getApplicationContext(), pictureURI) .setCallerTag(this) .setCallback( new ImageRequest.Callback() { @Override public void onCompleted(ImageResponse response) { processImageResponse(response, profileId, imageView); } }); ImageRequest newRequest = builder.build(); pendingRequests.put(profileId, newRequest); ImageDownloader.downloadAsync(newRequest); } }