Mam powiadomienie w mojej aplikacji. Powiadomienie zawiera tekst i obraz, który pobieram z LruCache, które zapełniam na początku. Problem polega na tym, że w moim przypadku Kit-Kat (Moto E, XIomi) powiadomienie przestaje się aktualizować, jeśli zostało już zaktualizowane określoną liczbę razy, powiedzmy n (to n jest zwykle stałe dla każdego urządzenia, i to < 10). To jest mój kod do aktualizacjiAndroid: Powiadomienie przestaje się aktualizować po aktualizacji określonej pewnej liczby razy na Kit-Kat
String title = CommonUtils.getTitleFromID(id, context);
Bitmap bitmap = DataProvider.getInstance(context).diskLruImageCache.getBitmap(id + "");
if (playbackPaused) {
bigView.setImageViewResource(R.id.pause, R.drawable.pause_noti);
smallView.setImageViewResource(R.id.pause1, R.drawable.pause_noti);
remoteViews.setImageViewResource(R.id.pause2, R.drawable.pause_noti);
playbackPaused = false;
Log.d(TAG, "noti-false");
}
bigView.setTextViewText(R.id.title, title + "");
bigView.setImageViewBitmap(R.id.img, bitmap);
smallView.setTextViewText(R.id.title1, title);
smallView.setImageViewBitmap(R.id.img1, bitmap);
mNotificationManager.notify(NOTIFY_ID, notification);
Próbowałem z odrobiną debugowania i wszystko i znalazłem że jeśli nie ustawić bitmapę, (i po prostu zrobić
bitmap = null
) następnie wszystko działa poprawnie.
Nie rozumiem, dlaczego tak się dzieje. Ten problem dotyczy wersji Androida, ponieważ testowałem już na Nexusie 5 (Lollipop) i innych telefonach z Androidem 5, ale tak się nie dzieje. Czy ktoś ma pojęcie, jaka może być tego przyczyna?
Nie oczekuję dokładnej sytuacji. Nawet niektóre pomysły we właściwym kierunku będą bardzo pomocne. Dzięki !!
Ja również dodanie kodu do mojego DiskLruCache w przypadku, gdy konieczna,
public class DiskLruImageCache {
private DiskLruCache mDiskCache;
private Bitmap.CompressFormat mCompressFormat = Bitmap.CompressFormat.JPEG;
private int mCompressQuality = 70;
private static final int APP_VERSION = 1;
private static final int VALUE_COUNT = 1;
private static final String TAG = "DiskLruImageCache";
public DiskLruImageCache(Context context,String uniqueName, int diskCacheSize,
Bitmap.CompressFormat compressFormat, int quality) {
try {
final File diskCacheDir = getDiskCacheDir(context, uniqueName);
mDiskCache = DiskLruCache.open(diskCacheDir, APP_VERSION, VALUE_COUNT, diskCacheSize);
mCompressFormat = compressFormat;
mCompressQuality = quality;
} catch (IOException e) {
e.printStackTrace();
}
}
private boolean writeBitmapToFile(Bitmap bitmap, DiskLruCache.Editor editor)
throws IOException {
OutputStream out = null;
try {
out = new BufferedOutputStream(editor.newOutputStream(0), Utils.IO_BUFFER_SIZE);
return bitmap.compress(mCompressFormat, mCompressQuality, out);
} finally {
if (out != null) {
out.close();
}
}
}
private boolean writeUriToFile(Uri bitmap, DiskLruCache.Editor editor)
throws IOException, FileNotFoundException {
OutputStream out = null;
try {
out = new BufferedOutputStream(editor.newOutputStream(0), Utils.IO_BUFFER_SIZE);
return true;
} finally {
if (out != null) {
out.close();
}
}
}
private File getDiskCacheDir(Context context, String uniqueName) {
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
final String cachePath =
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
!Utils.isExternalStorageRemovable() ?
Utils.getExternalCacheDir(context).getPath() :
context.getCacheDir().getPath();
return new File(cachePath + File.separator + uniqueName);
}
public void put(String key, Bitmap data) {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit(key);
if (editor == null) {
return;
}
if(writeBitmapToFile(data, editor)) {
mDiskCache.flush();
editor.commit();
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "image put on disk cache " + key);
}
} else {
editor.abort();
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "ERROR on: image put on disk cache " + key);
}
}
} catch (IOException e) {
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "ERROR on: image put on disk cache " + key);
}
try {
if (editor != null) {
editor.abort();
}
} catch (IOException ignored) {
}
}
}
public void put(String key, Uri data) {
DiskLruCache.Editor editor = null;
try {
editor = mDiskCache.edit(key);
if (editor == null) {
return;
}
if(writeUriToFile(data, editor)) {
mDiskCache.flush();
editor.commit();
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "image put on disk cache " + key);
}
} else {
editor.abort();
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "ERROR on: image put on disk cache " + key);
}
}
} catch (IOException e) {
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "ERROR on: image put on disk cache " + key);
}
try {
if (editor != null) {
editor.abort();
}
} catch (IOException ignored) {
}
}
}
public synchronized Bitmap getBitmap(String key) {
Bitmap bitmap = null;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get(key);
if (snapshot == null) {
return null;
}
final InputStream in = snapshot.getInputStream(0);
if (in != null) {
final BufferedInputStream buffIn =
new BufferedInputStream(in, Utils.IO_BUFFER_SIZE);
bitmap = BitmapFactory.decodeStream(buffIn);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (snapshot != null) {
snapshot.close();
}
}
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", bitmap == null ? "" : "image read from disk " + key);
}
return bitmap;
}
public boolean containsKey(String key) {
boolean contained = false;
DiskLruCache.Snapshot snapshot = null;
try {
snapshot = mDiskCache.get(key);
contained = snapshot != null;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (snapshot != null) {
snapshot.close();
}
}
return contained;
}
public boolean removeKey(String key) {
boolean removed=false;
DiskLruCache.Snapshot snapshot = null;
try {
removed = mDiskCache.remove(key);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (snapshot != null) {
snapshot.close();
}
}
return removed;
}
public void clearCache() {
if (BuildConfig.DEBUG) {
Log.d("cache_test_DISK_", "disk cache CLEARED");
}
try {
mDiskCache.delete();
} catch (IOException e) {
e.printStackTrace();
}
}
public File getCacheFolder() {
return mDiskCache.getDirectory();
}
}
tylko spostrzeżenie o kodzie i prawdopodobną przyczynę: You're nie uwalniając bitmap i można upaść z pamięci powierzchni. Czy masz jakieś ślady na temat problemu? – eduyayo
@eduyayo Hej, dzięki za odpowiedź, nie zauważyłem żadnych widocznych śladów. Ale gdzie i jak mam uwolnić bitmapę, ten problem jest dla mnie bardzo ważny, ale nie jestem w stanie go rozwiązać. Czy możesz zaproponować zmiany? Dzięki !! – varunkr
po "użyciu" powinieneś nazwać 'bitmap.recycle()'. Sugerowałbym, abyś utrzymywał odniesienie do poprzedniego używanego i recyklingu przed ustawieniem nowego ... – eduyayo