mirror of
https://github.com/samuelclay/NewsBlur.git
synced 2025-09-18 21:50:56 +00:00
Android widget image loading
This commit is contained in:
parent
0c439cae45
commit
35f6d47c6c
2 changed files with 65 additions and 112 deletions
|
@ -8,7 +8,6 @@ import java.util.concurrent.ExecutorService;
|
|||
import java.util.concurrent.Executors;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
|
@ -74,21 +73,34 @@ public class ImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
public WidgetPhotoToLoad displayWidgetImage(int widgetId, AppWidgetManager appWidgetManager, String url, RemoteViews remoteViews, int imageViewId) {
|
||||
if (url == null) {
|
||||
remoteViews.setImageViewResource(imageViewId, emptyRID);
|
||||
return null;
|
||||
/**
|
||||
* Synchronous background call coming from app widget on home screen
|
||||
*/
|
||||
public void displayWidgetImage(String url, int imageViewId, int maxDimPX, RemoteViews remoteViews) {
|
||||
url = buildUrlIfNeeded(url);
|
||||
|
||||
// try from memory
|
||||
Bitmap bitmap = memoryCache.get(url);
|
||||
if (bitmap != null) {
|
||||
remoteViews.setImageViewBitmap(imageViewId, bitmap);
|
||||
remoteViews.setViewVisibility(imageViewId, View.VISIBLE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (url.startsWith("/")) {
|
||||
url = APIConstants.buildUrl(url);
|
||||
// try from disk
|
||||
bitmap = getImageFromDisk(url, maxDimPX, false, 0f);
|
||||
if (bitmap == null) {
|
||||
// try for network
|
||||
bitmap = getImageFromNetwork(url, maxDimPX,false, 0f);
|
||||
}
|
||||
|
||||
WidgetPhotoToLoad widgetPhotoToLoad = new WidgetPhotoToLoad(widgetId, appWidgetManager, url, remoteViews, imageViewId);
|
||||
// PhotoToLoad photoToLoad = new PhotoToLoad(url, imageView, roundRadius, cropSquare, maxDimPX, allowDelay);
|
||||
|
||||
executorService.submit(new WidgetPhotoLoader(widgetPhotoToLoad));
|
||||
return widgetPhotoToLoad;
|
||||
if (bitmap != null) {
|
||||
memoryCache.put(url, bitmap);
|
||||
remoteViews.setImageViewBitmap(imageViewId, bitmap);
|
||||
remoteViews.setViewVisibility(imageViewId, View.VISIBLE);
|
||||
} else {
|
||||
remoteViews.setViewVisibility(imageViewId, View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
public PhotoToLoad displayImage(String url, ImageView imageView, float roundRadius, boolean cropSquare, int maxDimPX, boolean allowDelay) {
|
||||
|
@ -97,9 +109,7 @@ public class ImageLoader {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (url.startsWith("/")) {
|
||||
url = APIConstants.buildUrl(url);
|
||||
}
|
||||
url = buildUrlIfNeeded(url);
|
||||
|
||||
imageViewMappings.put(imageView, url);
|
||||
PhotoToLoad photoToLoad = new PhotoToLoad(url, imageView, roundRadius, cropSquare, maxDimPX, allowDelay);
|
||||
|
@ -108,21 +118,6 @@ public class ImageLoader {
|
|||
return photoToLoad;
|
||||
}
|
||||
|
||||
public static class WidgetPhotoToLoad {
|
||||
public int widgetId;
|
||||
public AppWidgetManager appWidgetManager;
|
||||
public String url;
|
||||
public RemoteViews remoteViews;
|
||||
public int imageViewId;
|
||||
public WidgetPhotoToLoad(int widgetId, final AppWidgetManager appWidgetManager, final String url, final RemoteViews remoteViews, final int imageViewId){
|
||||
WidgetPhotoToLoad.this.widgetId = widgetId;
|
||||
WidgetPhotoToLoad.this.appWidgetManager = appWidgetManager;
|
||||
WidgetPhotoToLoad.this.url = url;
|
||||
WidgetPhotoToLoad.this.remoteViews = remoteViews;
|
||||
WidgetPhotoToLoad.this.imageViewId = imageViewId;
|
||||
}
|
||||
}
|
||||
|
||||
public class PhotoToLoad {
|
||||
public String url;
|
||||
public ImageView imageView;
|
||||
|
@ -142,71 +137,6 @@ public class ImageLoader {
|
|||
}
|
||||
}
|
||||
|
||||
private class WidgetPhotoLoader implements Runnable {
|
||||
WidgetPhotoToLoad widgetPhotoToLoad;
|
||||
|
||||
public WidgetPhotoLoader(WidgetPhotoToLoad widgetPhotoToLoad) {
|
||||
this.widgetPhotoToLoad = widgetPhotoToLoad;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT + Process.THREAD_PRIORITY_LESS_FAVORABLE);
|
||||
// if (photoToLoad.cancel) return;
|
||||
|
||||
// try from memory
|
||||
Bitmap bitmap = memoryCache.get(widgetPhotoToLoad.url);
|
||||
|
||||
if (bitmap != null) {
|
||||
widgetPhotoToLoad.remoteViews.setImageViewBitmap(widgetPhotoToLoad.imageViewId, bitmap);
|
||||
// widgetPhotoToLoad.appWidgetManager.updateAppWidget(widgetPhotoToLoad.widgetId, widgetPhotoToLoad.remoteViews);
|
||||
return;
|
||||
}
|
||||
|
||||
// this not only sets a theoretical cap on how frequently we will churn against memory, storage, CPU,
|
||||
// and the UI handler, it also ensures that if the loader gets very behind (as happens during fast
|
||||
// scrolling, the caller has a few cycles to raise the cancellation flag, saving many resources.
|
||||
// if (photoToLoad.allowDelay) {
|
||||
// try {
|
||||
// Thread.sleep(20);
|
||||
// } catch (InterruptedException ie) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (photoToLoad.cancel) return;
|
||||
|
||||
// ensure this imageview even still wants this image
|
||||
// if (!isUrlMapped(photoToLoad.imageView, photoToLoad.url)) return;
|
||||
|
||||
// callers frequently might botch this due to lazy view measuring
|
||||
// if (photoToLoad.maxDimPX < 1) {
|
||||
// photoToLoad.maxDimPX = Integer.MAX_VALUE;
|
||||
// }
|
||||
|
||||
// try from disk
|
||||
File f = fileCache.getCachedFile(widgetPhotoToLoad.url);
|
||||
// the only reliable way to check a cached file is to try decoding it. the util method will
|
||||
// return null if it fails
|
||||
// bitmap = UIUtils.decodeImage(f, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
bitmap = UIUtils.decodeImage(f, 50, false, 4f);
|
||||
// try for network
|
||||
if (bitmap == null) {
|
||||
// if (widgetPhotoToLoad.cancel) return;
|
||||
fileCache.cacheFile(widgetPhotoToLoad.url);
|
||||
f = fileCache.getCachedFile(widgetPhotoToLoad.url);
|
||||
// bitmap = UIUtils.decodeImage(f, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
bitmap = UIUtils.decodeImage(f, 50, false, 4f);
|
||||
}
|
||||
|
||||
if (bitmap != null) {
|
||||
memoryCache.put(widgetPhotoToLoad.url, bitmap);
|
||||
}
|
||||
widgetPhotoToLoad.remoteViews.setImageViewBitmap(widgetPhotoToLoad.imageViewId, bitmap);
|
||||
// setViewImage(bitmap, photoToLoad);
|
||||
}
|
||||
}
|
||||
|
||||
private class PhotosLoader implements Runnable {
|
||||
PhotoToLoad photoToLoad;
|
||||
|
||||
|
@ -249,16 +179,11 @@ public class ImageLoader {
|
|||
}
|
||||
|
||||
// try from disk
|
||||
File f = fileCache.getCachedFile(photoToLoad.url);
|
||||
// the only reliable way to check a cached file is to try decoding it. the util method will
|
||||
// return null if it fails
|
||||
bitmap = UIUtils.decodeImage(f, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
// try for network
|
||||
bitmap = getImageFromDisk(photoToLoad.url, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
if (bitmap == null) {
|
||||
// try for network
|
||||
if (photoToLoad.cancel) return;
|
||||
fileCache.cacheFile(photoToLoad.url);
|
||||
f = fileCache.getCachedFile(photoToLoad.url);
|
||||
bitmap = UIUtils.decodeImage(f, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
bitmap = getImageFromNetwork(photoToLoad.url, photoToLoad.maxDimPX, photoToLoad.cropSquare, photoToLoad.roundRadius);
|
||||
}
|
||||
|
||||
if (bitmap != null) {
|
||||
|
@ -326,4 +251,23 @@ public class ImageLoader {
|
|||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
private String buildUrlIfNeeded(String url) {
|
||||
if (url.startsWith("/")) {
|
||||
url = APIConstants.buildUrl(url);
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
private Bitmap getImageFromDisk(String url, int maxDimPX, boolean cropSquare, float roundRadius) {
|
||||
// the only reliable way to check a cached file is to try decoding it. the util method will
|
||||
// return null if it fails
|
||||
File f = fileCache.getCachedFile(url);
|
||||
return UIUtils.decodeImage(f, maxDimPX, cropSquare, roundRadius);
|
||||
}
|
||||
|
||||
private Bitmap getImageFromNetwork(String url, int maxDimPX, boolean cropSquare, float roundRadius) {
|
||||
fileCache.cacheFile(url);
|
||||
File f = fileCache.getCachedFile(url);
|
||||
return UIUtils.decodeImage(f, maxDimPX, cropSquare, roundRadius);
|
||||
}
|
||||
}
|
|
@ -9,7 +9,8 @@ import android.os.Bundle;
|
|||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.content.Loader;
|
||||
import android.util.Log;
|
||||
import android.text.TextUtils;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
import android.widget.RemoteViewsService;
|
||||
|
||||
|
@ -17,6 +18,7 @@ import com.newsblur.R;
|
|||
import com.newsblur.domain.Story;
|
||||
import com.newsblur.util.FeedSet;
|
||||
import com.newsblur.util.FeedUtils;
|
||||
import com.newsblur.util.Log;
|
||||
import com.newsblur.util.PrefsUtils;
|
||||
import com.newsblur.util.StoryUtils;
|
||||
import com.newsblur.util.ThumbnailStyle;
|
||||
|
@ -36,8 +38,8 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
private int appWidgetId;
|
||||
private boolean skipCursorUpdate;
|
||||
|
||||
public WidgetRemoteViewsFactory(Context context, Intent intent) {
|
||||
Log.d(TAG, "Constructor");
|
||||
WidgetRemoteViewsFactory(Context context, Intent intent) {
|
||||
com.newsblur.util.Log.d(TAG, "Constructor");
|
||||
this.context = context;
|
||||
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID);
|
||||
|
@ -101,7 +103,7 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
*/
|
||||
@Override
|
||||
public RemoteViews getViewAt(int position) {
|
||||
Log.d(TAG, "getViewAt " + position);
|
||||
com.newsblur.util.Log.d(TAG, "getViewAt " + position);
|
||||
Story story = storyItems.get(position);
|
||||
|
||||
WidgetRemoteViews rv = new WidgetRemoteViews(context.getPackageName(), R.layout.view_widget_story_item);
|
||||
|
@ -110,9 +112,12 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
rv.setTextViewText(R.id.story_item_author, story.authors);
|
||||
rv.setTextViewText(R.id.story_item_feedtitle, story.extern_feedTitle);
|
||||
|
||||
FeedUtils.iconLoader.displayWidgetImage(appWidgetId, AppWidgetManager.getInstance(context), story.extern_faviconUrl, rv, R.id.story_item_feedicon);
|
||||
if (PrefsUtils.getThumbnailStyle(context) != ThumbnailStyle.OFF && story.thumbnailUrl != null) {
|
||||
// FeedUtils.thumbnailLoader.displayWidgetImage(appWidgetId, AppWidgetManager.getInstance(context), story.thumbnailUrl, rv, R.id.story_item_thumbnail);
|
||||
// image dimensions same as R.layout.view_widget_story_item
|
||||
FeedUtils.iconLoader.displayWidgetImage(story.extern_faviconUrl, R.id.story_item_feedicon, UIUtils.dp2px(context, 18), rv);
|
||||
if (PrefsUtils.getThumbnailStyle(context) != ThumbnailStyle.OFF && !TextUtils.isEmpty(story.thumbnailUrl)) {
|
||||
FeedUtils.thumbnailLoader.displayWidgetImage(story.thumbnailUrl, R.id.story_item_thumbnail, UIUtils.dp2px(context, 64), rv);
|
||||
} else {
|
||||
rv.setViewVisibility(R.id.story_item_thumbnail, View.GONE);
|
||||
}
|
||||
|
||||
//TODO: authors and dates don't get along
|
||||
|
@ -200,7 +205,11 @@ public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsF
|
|||
*/
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
Log.d(TAG, "onDestroy");
|
||||
com.newsblur.util.Log.d(TAG, "onDestroy");
|
||||
if (cursor != null) {
|
||||
cursor.close();
|
||||
}
|
||||
PrefsUtils.removeWidgetFeed(context, appWidgetId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue