OutOfMemory Error seems to be fixed

This commit is contained in:
daniel oeh 2012-07-06 15:55:20 +02:00
parent 7b86821cd8
commit ac755c8899
8 changed files with 49 additions and 11 deletions

View File

@ -1,8 +1,9 @@
package de.podfetcher; package de.podfetcher;
import de.podfetcher.activity.PodfetcherActivity;
import de.podfetcher.feed.FeedManager;
import android.app.Application; import android.app.Application;
import android.util.Log;
import de.podfetcher.asynctask.FeedImageLoader;
import de.podfetcher.feed.FeedManager;
public class PodcastApp extends Application { public class PodcastApp extends Application {
private static final String TAG = "PodcastApp"; private static final String TAG = "PodcastApp";
@ -23,6 +24,13 @@ public class PodcastApp extends Application {
FeedManager manager = FeedManager.getInstance(); FeedManager manager = FeedManager.getInstance();
manager.loadDBData(getApplicationContext()); manager.loadDBData(getApplicationContext());
} }
@Override
public void onLowMemory() {
super.onLowMemory();
Log.w(TAG, "Received onLowOnMemory warning. Cleaning image cache...");
FeedImageLoader.getInstance().wipeImageCache();
}

View File

@ -58,6 +58,8 @@ public class FeedInfoActivity extends SherlockActivity {
} }
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
return true; return true;

View File

@ -9,6 +9,7 @@ import android.os.Bundle;
import android.support.v4.app.Fragment; import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager;
import android.util.Log; import android.util.Log;
@ -135,7 +136,7 @@ public class PodfetcherActivity extends SherlockFragmentActivity {
return true; return true;
} }
public static class MainPagerAdapter extends FragmentPagerAdapter { public static class MainPagerAdapter extends FragmentStatePagerAdapter {
private static final int NUM_ITEMS = 3; private static final int NUM_ITEMS = 3;
private static final int POS_FEEDLIST = 0; private static final int POS_FEEDLIST = 0;

View File

@ -62,6 +62,11 @@ public class FeedlistAdapter extends ArrayAdapter<Feed> {
convertView.setTag(holder); convertView.setTag(holder);
} else { } else {
holder = (Holder) convertView.getTag(); holder = (Holder) convertView.getTag();
// Recycle images which are no longer in the cache
if (!FeedImageLoader.getInstance().isInCache(feed.getImage())) {
Log.d(TAG, "Deleting reference to uncached bitmap");
holder.image.setImageBitmap(null);
}
} }
if (position == selectedItemIndex) { if (position == selectedItemIndex) {

View File

@ -1,8 +1,11 @@
package de.podfetcher.asynctask; package de.podfetcher.asynctask;
import de.podfetcher.PodcastApp;
import de.podfetcher.R; import de.podfetcher.R;
import de.podfetcher.feed.FeedImage; import de.podfetcher.feed.FeedImage;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.BitmapFactory; import android.graphics.BitmapFactory;
import android.os.AsyncTask; import android.os.AsyncTask;
@ -12,17 +15,24 @@ import android.widget.ImageView;
/** Caches and loads FeedImage bitmaps in the background */ /** Caches and loads FeedImage bitmaps in the background */
public class FeedImageLoader { public class FeedImageLoader {
private static final String TAG = "FeedImageLoader";
private static FeedImageLoader singleton; private static FeedImageLoader singleton;
/** /**
* Stores references to loaded bitmaps. Bitmaps can be accessed by the id of * Stores references to loaded bitmaps. Bitmaps can be accessed by the id of
* the FeedImage the bitmap belongs to. * the FeedImage the bitmap belongs to.
*/ */
final int memClass = ((ActivityManager) PodcastApp.getInstance()
.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass();
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = 1024 * 1024 * memClass / 8;
private LruCache<Long, Bitmap> imageCache; private LruCache<Long, Bitmap> imageCache;
private static final int CACHE_SIZE = 4 * 1024 * 1024;
private FeedImageLoader() { private FeedImageLoader() {
imageCache = new LruCache<Long, Bitmap>(CACHE_SIZE) { Log.d(TAG, "Creating cache with size " + cacheSize);
imageCache = new LruCache<Long, Bitmap>(cacheSize) {
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Override @Override
@ -63,6 +73,14 @@ public class FeedImageLoader {
imageCache.put(id, bitmap); imageCache.put(id, bitmap);
} }
public void wipeImageCache() {
imageCache.evictAll();
}
public boolean isInCache(FeedImage image) {
return imageCache.get(image.getId()) != null;
}
public Bitmap getBitmapFromCache(long id) { public Bitmap getBitmapFromCache(long id) {
return imageCache.get(id); return imageCache.get(id);
} }

View File

@ -179,10 +179,10 @@ public class FeedManager {
public long addDownloadStatus(Context context, DownloadStatus status) { public long addDownloadStatus(Context context, DownloadStatus status) {
PodDBAdapter adapter = new PodDBAdapter(context); PodDBAdapter adapter = new PodDBAdapter(context);
downloadLog.add(status); downloadLog.add(status);
adapter.open();
if (downloadLog.size() > DOWNLOAD_LOG_SIZE) { if (downloadLog.size() > DOWNLOAD_LOG_SIZE) {
adapter.removeDownloadStatus(downloadLog.remove(0)); adapter.removeDownloadStatus(downloadLog.remove(0));
} }
adapter.open();
long result = adapter.setDownloadStatus(status); long result = adapter.setDownloadStatus(status);
adapter.close(); adapter.close();
return result; return result;

View File

@ -52,6 +52,8 @@ public class FeedlistFragment extends SherlockListFragment implements
pActivity = null; pActivity = null;
} }
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -175,4 +177,5 @@ public class FeedlistFragment extends SherlockListFragment implements
selectedFeed = null; selectedFeed = null;
fla.setSelectedItemIndex(FeedlistAdapter.SELECTION_NONE); fla.setSelectedItemIndex(FeedlistAdapter.SELECTION_NONE);
} }
} }

View File

@ -297,16 +297,17 @@ public class DownloadService extends Service {
try { try {
feed = handler.parseFeed(feed); feed = handler.parseFeed(feed);
Log.d(TAG, feed.getTitle() + " parsed"); Log.d(TAG, feed.getTitle() + " parsed");
// Download Feed Image if provided
if (feed.getImage() != null) { feed.setDownloadId(0);
// Save information of feed in DB
savedFeed = manager.updateFeed(service, feed);
// Download Feed Image if provided and not downloaded
if (savedFeed.getImage().isDownloaded() == false) {
Log.d(TAG, "Feed has image; Downloading...."); Log.d(TAG, "Feed has image; Downloading....");
imageId = requester.downloadImage(service, feed.getImage()); imageId = requester.downloadImage(service, feed.getImage());
hasImage = true; hasImage = true;
} }
feed.setDownloadId(0);
// Save information of feed in DB
savedFeed = manager.updateFeed(service, feed);
} catch (SAXException e) { } catch (SAXException e) {
successful = false; successful = false;
e.printStackTrace(); e.printStackTrace();