Improve image pre-caching

This commit is contained in:
David-Development 2014-08-31 10:05:07 +02:00
parent d98f9fca9b
commit 5ee44f5acb
8 changed files with 54 additions and 274 deletions

View file

@ -534,10 +534,9 @@ public class NewsReaderListActivity extends MenuUtilsFragmentActivity implements
case R.id.menu_StartImageCaching:
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(this);
long highestItemId = dbConn.getLowestRssItemIdUnread();//TODO needs testing!
long highestItemId = dbConn.getLowestRssItemIdUnread();
Intent service = new Intent(this, DownloadImagesService.class);
service.putExtra(DownloadImagesService.LAST_ITEM_ID, highestItemId);
//service.putExtra(DownloadImagesService.DOWNLOAD_FAVICONS_EXCLUSIVE, true);
startService(service);
break;

View file

@ -42,7 +42,7 @@ import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache;
import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
public class GetImageAsyncTask extends AsyncTask<Void, Void, Bitmap>
{
private static final String TAG = "GetImageAsyncTask";
@ -54,17 +54,16 @@ public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
private String rootPath;
private Context cont;
private BitmapDrawableLruCache lruCache;
public Long feedID = null;
public boolean scaleImage = false;
public int dstHeight; // height in pixels
public int dstWidth; // width in pixels
Bitmap bmp;
//private ImageView imgView;
//private WeakReference<ImageView> imageViewReference;
public GetImageAsyncTask(String WEB_URL_TO_FILE, ImageDownloadFinished imgDownloadFinished, int AsynkTaskId, String rootPath, Context cont/*, ImageView imageView*/, BitmapDrawableLruCache lruCache) {
public GetImageAsyncTask(String WEB_URL_TO_FILE, ImageDownloadFinished imgDownloadFinished, int AsynkTaskId, String rootPath, Context cont, Long feedId) {
try
{
this.WEB_URL_TO_FILE = new URL(WEB_URL_TO_FILE);
@ -74,7 +73,8 @@ public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
Log.d(TAG, ex.getLocalizedMessage() + " - URL: " + WEB_URL_TO_FILE);
//ex.printStackTrace();
}
this.lruCache = lruCache;
this.feedID = feedID;
this.cont = cont;
imageDownloadFinished = imgDownloadFinished;
this.AsyncTaskId = AsynkTaskId;
@ -83,9 +83,9 @@ public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
}
@Override
protected void onPostExecute(String result) {
protected void onPostExecute(Bitmap result) {
if(imageDownloadFinished != null)
imageDownloadFinished.DownloadFinished(AsyncTaskId, result, lruCache);
imageDownloadFinished.DownloadFinished(AsyncTaskId, feedID, result);
//imgView.setImageDrawable(GetFavIconFromCache(WEB_URL_TO_FILE.toString(), context));
super.onPostExecute(result);
}
@ -93,7 +93,7 @@ public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
@SuppressWarnings("deprecation")
@SuppressLint("NewApi")
@Override
protected String doInBackground(Void... params) {
protected Bitmap doInBackground(Void... params) {
try
{
File cacheFile = ImageHandler.getFullPathOfCacheFile(WEB_URL_TO_FILE.toString(), rootPath);
@ -127,71 +127,25 @@ public class GetImageAsyncTask extends AsyncTask<Void, Void, String>
baf.append((byte) current);
}
if(lruCache != null) {
if(lruCache.get(feedID) == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(baf.toByteArray(), 0, baf.length());
if(feedID != null && bmp != null)
lruCache.put(feedID, new BitmapDrawable(bmp));
}
}
/* Convert the Bytes read to a String. */
bmp = BitmapFactory.decodeByteArray(baf.toByteArray(), 0, baf.length());
//If the file is not empty
if(baf.length() > 0) {
FileOutputStream fos = new FileOutputStream(cacheFile);
fos.write(baf.toByteArray());
fos.close();
/*
FileOutputStream fOut = new FileOutputStream(cacheFile);
Bitmap mBitmap = BitmapFactory.decodeStream(WEB_URL_TO_FILE.openStream());
Log.d(TAG, "Downloading image: " + WEB_URL_TO_FILE.toString());
if(mBitmap != null) {
if(scaleImage)
mBitmap = Bitmap.createScaledBitmap(mBitmap, dstWidth, dstHeight, true);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
}
fOut.close();
*/
/*
count++;
if(count >= 25)//Check every 25 images the cache size
{
count = 0;
HashMap<File, Long> files;
long size = ImageHandler.getFolderSize(new File(ImageHandler.getPath(cont)));
size = (long) (size / 1024d / 1024d);
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(cont);
int max_allowed_size = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_MAX_CACHE_SIZE, "1000"));//Default is 1Gb --> 1000mb
if(size > max_allowed_size)
{
files = new HashMap<File, Long>();
for(File file : ImageHandler.getFilesFromDir(new File(ImageHandler.getPathImageCache(cont))))
{
files.put(file, file.lastModified());
}
for(Object itemObj : sortHashMapByValuesD(files).entrySet())
{
File file = (File) itemObj;
file.delete();
size -= file.length();
if(size < max_allowed_size)
break;
}
}
} */
}
return cacheFile.getPath();
//return cacheFile.getPath();
}
catch(Exception ex)
{
//ex.printStackTrace();
}
return null;
return bmp;
}

View file

@ -43,6 +43,12 @@ import de.luhmer.owncloudnewsreader.database.model.Feed;
public class FavIconHandler {
private static final String TAG = "FavIconHandler";
Context context;
public FavIconHandler(Context context) {
this.context = context;
}
public static Drawable GetFavIconFromCache(String URL_TO_PAGE, Context context, Long feedID)
{
try
@ -81,110 +87,29 @@ public class FavIconHandler {
}
static SparseArray<FavIconCache> imageViewReferences = new SparseArray<FavIconCache>();
Long feedID;
static SparseArray<FavIconCache> favIconToFeedId = new SparseArray<FavIconCache>();
public static void PreCacheFavIcon(String WEB_URL_TO_FILE, Context context, Long feedID) {
FavIconCache favIconCache = new FavIconCache();
favIconCache.context = context;
favIconCache.WEB_URL_TO_FILE = WEB_URL_TO_FILE;
public void PreCacheFavIcon(String WEB_URL_TO_FILE, Long feedID) {
int key = feedID.intValue();
favIconToFeedId.put(key, favIconCache);
GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, favIconDownloadFinished, key, FileUtils.getPathFavIcons(context), context, null);
GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, favIconDownloadFinished, key, FileUtils.getPathFavIcons(context), context, feedID);
giAsync.scaleImage = true;
giAsync.dstHeight = 2*32;
giAsync.dstWidth = 2*32;
giAsync.feedID = feedID;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
// Execute in parallel
giAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void)null));
else
giAsync.execute((Void)null);
AsyncTaskHelper.StartAsyncTask(giAsync, ((Void)null));
}
static ImageDownloadFinished favIconDownloadFinished = new ImageDownloadFinished() {
ImageDownloadFinished favIconDownloadFinished = new ImageDownloadFinished() {
@Override
public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) {
FavIconCache favIconCache = favIconToFeedId.get(AsynkTaskId);
FavIconHandler.GetFavIconFromCache(favIconCache.WEB_URL_TO_FILE, favIconCache.context, (long) AsynkTaskId);
imageViewReferences.remove(AsynkTaskId);
public void DownloadFinished(int AsynkTaskId, Long feedId, Bitmap bitmap) {
if(bitmap != null) {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(context);
Feed feed = dbConn.getFeedById(feedId);
String avg = ColourCalculator.ColourHexFromBitmap(bitmap);
feed.setAvgColour(avg);
dbConn.updateFeed(feed);
}
}
};
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public void GetImageAsync(ImageView imageView, String WEB_URL_TO_FILE, Context context, Long feedID, BitmapDrawableLruCache lruCache)
{
this.feedID = feedID;
boolean setImageAlready = false;
if(lruCache != null) {
if(lruCache.get(feedID) != null) {
if (imageView != null) {
imageView.setImageDrawable(lruCache.get(feedID));
setImageAlready = true;
}
}
}
if(!setImageAlready) {
WeakReference<ImageView> imageViewReference = new WeakReference<ImageView>(imageView);
FavIconCache favIconCache = new FavIconCache();
favIconCache.context = context;
favIconCache.WEB_URL_TO_FILE = WEB_URL_TO_FILE;
favIconCache.imageViewReference = imageViewReference;
int key = 0;
if(imageViewReferences.size() > 0)
key = imageViewReferences.keyAt(imageViewReferences.size() -1) + 1;
imageViewReferences.append(key, favIconCache);
imageView.setImageDrawable(null);
GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, imgDownloadFinished, key, FileUtils.getPathFavIcons(context), context/*, imageView*/, lruCache);
giAsync.scaleImage = true;
giAsync.dstHeight = 2*32;
giAsync.dstWidth = 2*32;
giAsync.feedID = feedID;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
giAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void)null));
else
giAsync.execute((Void)null);
}
}
ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() {
@Override
public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) {
//WeakReference<ImageView> imageViewRef = imageViewReferences.get(AsynkTaskId);
FavIconCache favIconCache = imageViewReferences.get(AsynkTaskId);
WeakReference<ImageView> imageViewRef = favIconCache.imageViewReference;
if(imageViewRef != null)
{
ImageView imageView = imageViewRef.get();
if (imageView != null) {
BitmapDrawable bd = (BitmapDrawable) FavIconHandler.GetFavIconFromCache(favIconCache.WEB_URL_TO_FILE, favIconCache.context, feedID);
if(lruCache != null && feedID != null && bd != null)
lruCache.put(feedID, bd);
imageView.setImageDrawable(bd);
}
}
imageViewReferences.remove(AsynkTaskId);
}
};
static class FavIconCache
{
public WeakReference<ImageView> imageViewReference;
public String WEB_URL_TO_FILE;
public Context context;
}
}

View file

@ -22,6 +22,9 @@
package de.luhmer.owncloudnewsreader.helper;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
public interface ImageDownloadFinished {
void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache);
void DownloadFinished(int AsynkTaskId, @NonNull Long feedId, Bitmap bitmap);
}

View file

@ -1,65 +0,0 @@
/**
* Android ownCloud News
*
* @author David Luhmer
* @copyright 2013 David Luhmer david-dev@live.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.luhmer.owncloudnewsreader.reader;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Build;
import android.util.SparseArray;
import de.luhmer.owncloudnewsreader.async_tasks.GetImageAsyncTask;
import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache;
import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished;
public class DownloadItemsToCache {
SparseArray<String> URLs;
Context context;
public DownloadItemsToCache(Context context) {
URLs = new SparseArray<String>();
this.context = context;
}
public void StartDownloadOfImage(String URL_TO_IMAGE)
{
int key = 0;
if(URLs.size() > 0)
key = URLs.keyAt(URLs.size() -1) + 1;
URLs.append(key, URL_TO_IMAGE);
GetImageAsyncTask getImageAsync = new GetImageAsyncTask(URL_TO_IMAGE, imgDownloadFinished, key, FileUtils.getPathImageCache(context), context, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getImageAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) null));// Execute in parallel
else
getImageAsync.execute((Void)null);
}
ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() {
@Override
public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) {
}
};
}

View file

@ -135,12 +135,12 @@ public class AsyncTask_GetItems extends AsyncTask_Reader {
listenerInstance.onAsyncTaskCompleted(task_id, ex);
}
if(ex != null) {
if(ex == null && NetworkConnection.isNetworkAvailable(context)) {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
if (mPrefs.getBoolean(SettingsActivity.CB_CACHE_IMAGES_OFFLINE_STRING, false)) {
if (!NetworkConnection.isWLANConnected(context) && NetworkConnection.isNetworkAvailable(context))
if (!NetworkConnection.isWLANConnected(context))
ShowDownloadImageWithoutWifiQuestion();
else if (NetworkConnection.isNetworkAvailable(context))
else
StartDownloadingImages(context, highestItemIdBeforeSync, false);
} else {
StartDownloadingImages(context, highestItemIdBeforeSync, true);
@ -150,6 +150,12 @@ public class AsyncTask_GetItems extends AsyncTask_Reader {
detach();
}
/**
*
* @param context
* @param highestItemIdBeforeSync
* @param favIconsExclusive indicates if only favIcons should be downloaded
*/
public static void StartDownloadingImages(Context context, long highestItemIdBeforeSync, boolean favIconsExclusive)
{
Intent service = new Intent(context, DownloadImagesService.class);
@ -185,32 +191,5 @@ public class AsyncTask_GetItems extends AsyncTask_Reader {
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
//final Context contextDownloadImage = this.context;
/*
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
// set title
alertDialogBuilder.setTitle(contextDownloadImage.getString(R.string.no_wifi_available));
// set dialog message
alertDialogBuilder
.setMessage(contextDownloadImage.getString(R.string.do_you_want_to_download_without_wifi))
.setCancelable(true)
.setPositiveButton(contextDownloadImage.getString(android.R.string.yes) ,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
StartDownloadingImages(contextDownloadImage);
}
})
.setNegativeButton(contextDownloadImage.getString(android.R.string.no) ,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
*/
}
}

View file

@ -28,6 +28,7 @@ import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.preference.PreferenceManager;
import android.support.v4.app.NotificationCompat;
import android.util.SparseArray;
@ -91,13 +92,6 @@ public class DownloadImagesService extends IntentService {
{
if(maxCount == 0)
notificationManager.cancel(NOTIFICATION_ID);
/*
else if(maxCount != count)
{
NotificationDownloadImages.setProgress(maxCount, count, false);
NotificationDownloadImages.setContentText("Stopped downloading images. Application was closed.");
notificationManager.notify(NOTIFICATION_ID, NotificationDownloadImages.build());
}*/
}
super.onDestroy();
}
@ -116,7 +110,7 @@ public class DownloadImagesService extends IntentService {
for(int i = 0; i < linksFavIcons.size(); i++) {
int key = linksFavIcons.keyAt(i);
String link = linksFavIcons.get(i);
FavIconHandler.PreCacheFavIcon(link, this, (long) key);
new FavIconHandler(this).PreCacheFavIcon(link, (long) key);
}
@ -219,16 +213,7 @@ public class DownloadImagesService extends IntentService {
ImageDownloadFinished imgDownloadFinished = new ImageDownloadFinished() {
@Override
public void DownloadFinished(int AsynkTaskId, String fileCachePath, BitmapDrawableLruCache lruCache) {
if(fileCachePath != null) {
File file = new File(fileCachePath);
long size = file.length();
//total_size += size;
if(size == 0)
file.delete();
}
public void DownloadFinished(int AsynkTaskId, Long feedId, Bitmap bitmap) {
count++;
// Sets the progress indicator to a max value, the