NoSuchMethodError using LruCache on Android

I got an error using a custom class that inherits from LruCache on Android. It should upload images and cache them; It worked yesterday, but this morning I ran into this problem.

This is the class code:

public class LruMemoryCache extends LruCache<String, Bitmap> { private final Context context; private static LruMemoryCache instance; private LruMemoryCache(Context context) { // super(1024 * 1024 * (((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass()) / 8); super(5 * 1024 * 1024); this.context = context; } public static synchronized LruMemoryCache getInstance(Context context) { if (instance == null) { instance = new LruMemoryCache(context); } return instance; } @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } public void loadBitmap(String url, ImageView imageView) { final String imageKey = url; final Bitmap bitmap = get(imageKey); if (bitmap != null) { imageView.setImageBitmap(bitmap); } else { BitmapWorkerTask task = new BitmapWorkerTask(imageView); task.execute(url); } } class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> { Bitmap myBitmap; ImageView mImageView; public BitmapWorkerTask(ImageView imageView) { mImageView = imageView; } @Override protected Bitmap doInBackground(String... params) { try { URL url = new URL("http://www.google.com/logos/classicplus.png"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setDoInput(true); connection.connect(); InputStream input = connection.getInputStream(); myBitmap = BitmapFactory.decodeStream(input); } catch (IOException e) { e.printStackTrace(); } put(params[0], myBitmap); return myBitmap; } @Override protected void onPostExecute(Bitmap result) { super.onPostExecute(result); mImageView.setImageBitmap(result); } } } 

And this is the LogCat error:

 05-15 08:02:08.639: E/AndroidRuntime(12818): FATAL EXCEPTION: AsyncTask #2 05-15 08:02:08.639: E/AndroidRuntime(12818): java.lang.RuntimeException: An error occured while executing doInBackground() 05-15 08:02:08.639: E/AndroidRuntime(12818): at android.os.AsyncTask$3.done(AsyncTask.java:200) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.FutureTask.run(FutureTask.java:138) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.lang.Thread.run(Thread.java:1019) 05-15 08:02:08.639: E/AndroidRuntime(12818): Caused by: java.lang.NoSuchMethodError: getByteCount 05-15 08:02:08.639: E/AndroidRuntime(12818): at com.xs2theworld.sundio.caching.LruMemoryCache.sizeOf(LruMemoryCache.java:36) 05-15 08:02:08.639: E/AndroidRuntime(12818): at com.xs2theworld.sundio.caching.LruMemoryCache.sizeOf(LruMemoryCache.java:1) 05-15 08:02:08.639: E/AndroidRuntime(12818): at android.support.v4.util.LruCache.safeSizeOf(LruCache.java:230) 05-15 08:02:08.639: E/AndroidRuntime(12818): at android.support.v4.util.LruCache.put(LruCache.java:123) 05-15 08:02:08.639: E/AndroidRuntime(12818): at com.xs2theworld.sundio.caching.LruMemoryCache$BitmapWorkerTask.doInBackground(LruMemoryCache.java:72) 05-15 08:02:08.639: E/AndroidRuntime(12818): at com.xs2theworld.sundio.caching.LruMemoryCache$BitmapWorkerTask.doInBackground(LruMemoryCache.java:1) 05-15 08:02:08.639: E/AndroidRuntime(12818): at android.os.AsyncTask$2.call(AsyncTask.java:185) 05-15 08:02:08.639: E/AndroidRuntime(12818): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 05-15 08:02:08.639: E/AndroidRuntime(12818): ... 4 more 

Any idea why this might happen?

Thanks to all in advance to all.

EDIT: I just realized that this error does not happen with the Google Galaxy Nexus S phone, but it happens with the Samsun Galaxy .. does anyone know why?

+4
source share
3 answers

The problem is caused by:

 @Override protected int sizeOf(String key, Bitmap value) { return value.getByteCount(); } 

The getByteCount () method can only be used with API> = 12, and Samsung Galaxy uses API 10.

Decision:

 @Override protected int sizeOf(String key, Bitmap value) { if (Integer.valueOf(android.os.Build.VERSION.SDK_INT) >= 12) return value.getByteCount(); else return (value.getRowBytes() * value.getHeight()); } 
+6
source

for LruCache, use the google support library or get the source code.

it’s usually quite difficult to understand what they did in the source code, but this time it’s pretty easy.

+1
source

I tried all of the above methods, and they were close, but not quite correct (at least for my situation).

I used bitmap.getByteCount (); inside the sizeOf () method when creating a new LruCache:

 mMemoryCache = new LruCache<String, Bitmap>(cacheSize) { @Override protected int sizeOf(String key, Bitmap bitmap) { return bitmap.getByteCount(); } }; 

Then I tried to suggest:

 return bitmap.getRowBytes() * bitmap.getHeight(); 

It was great, but I noticed that the return values ​​were different, and when I used the sentence suggested above, it would not even make a cache on my device. I tested return values ​​on Nexus One running on api 3.2 and Galaxy Nexus running on 4.2:

 bitmap.getByteCount(); returned-> 15 bitmap.getRowBytes() * bitmap.getHeight(); returned-> 15400 

So, to solve my problem, I just did this:

 return (bitmap.getRowBytes() * bitmap.getHeight()) / 1000; 

instead:

 return bitmap.getByteCount(); 

There may not be the same situation you were in, but it worked for me.

+1
source

Source: https://habr.com/ru/post/1412513/


All Articles