Out of Memory Picasso Lib - android

I'm developing an app that loads a lot of images through lib Picasso. When I'm navigating through the app, suddenly the app crashes, giving out of memory.
I already tried to do somethings to avoid this kind of problem, but with no success.
If someone could help me, i would be glad.
Below the code:
java.lang.RuntimeException: Unable to start activity
ComponentInfo{com.codal.whatsee/com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity}: android.view.InflateException: Binary
XML file line #55: Error inflating class <unknown>
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2217)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2266)
at android.app.ActivityThread.access$800(ActivityThread.java:145)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1206)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5141)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:611)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.view.InflateException: Binary XML file line #55: Error inflating class <unknown>
at android.view.LayoutInflater.createView(LayoutInflater.java:620)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:758)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at android.view.LayoutInflater.inflate(LayoutInflater.java:353)
at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:343)
at android.app.Activity.setContentView(Activity.java:1929)
at com.codal.whatsee.fragmentactivity.ItemPostFragmentActivity.onCreate(ItemPostFragmentActivity.java:150)
at android.app.Activity.performCreate(Activity.java:5231)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2171)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at java.lang.reflect.Constructor.constructNative(Native Method)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at android.view.LayoutInflater.createView(LayoutInflater.java:594)
... 23 more
Caused by: java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:594)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:429)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:840)
at android.content.res.Resources.loadDrawable(Resources.java:2208)
at android.content.res.TypedArray.getDrawable(TypedArray.java:602)
at android.widget.ImageView.<init>(ImageView.java:129)
at android.widget.ImageView.<init>(ImageView.java:119)
at com.codal.whatsee.utils.SquareImageView.<init>(SquareImageView.java:13)
... 26 more
OBS: This problem happens not just in this class, but in any other class happens too.

This sounds a lot like your application is leaking memory and the image decoding is just the last operation that fills the heap. You should use the android DDMS tools and create a heap dump of your app after short use. If you see many Activities or Fragments in the dump, you should try to figure out which objects are still holding references to them.
Here is the related page from the developer site:
https://developer.android.com/tools/debugging/debugging-memory.html

You can expect such exception when dealing with images and bitmap. In present case it appears that out of memory is due to loading of a large/big image which consume the available memory and creating issue.
Luckily picasso lib offers an option to scale down your image so that it may not consumed much memory and thus lower down the chances for getting out of memory exception.
See if this below code is helpful to you or not.
Picasso.with(context).load(file).resize(sizeToScaleDown, sizeToSacleDown).onlyScaleDown().into(imageView);
Note: onlyScaleDown() function only works if you have also used resize() function. Using onlyScaleDown() function without resize() function will cause you exception.

Android 4.2 and 4.3 do not free the memory for a bitmap unless you finish the activity using the bitmap or recycle it (Bitmap.recycle()). See Android Bitmap Memory Analysis - Part 3. API Version Comparison for a detailed analysis. In Android 4.3 you need to additionally remove the image view from the view hierarchy.
So if you have an app where you can build up a deep navigation history and are using Picasso, you will run out of memory sooner or later because Picasso does not track references to bitmaps and therefore cannot call Bitmap.recycle() for them.
We had a similar issue and finally switched to Facebook's Fresco library, which goes at great length to track references. It is therefore more complex too use but it pays off.

You may be getting OOM because of the following:
You are doing some operation that continuously demands a lot of memory. Like Picasso Lib fetching large images/bitmaps which plays with bitmap operations
Picasso uses fit() or resize() methods while fetching the images. ReferenceLink
Memory leaks: You didn’t made the previous objects you allocated eligible for Garbage Collection (GC)
Use memory analyzer tool for taking Dump check where object are getting leak.
Dealing with large bitmaps. Scaling and bitmap operation take the memory from the heap.
I came across this link. It may help you : Link

Related

Samsung device allocates memory on back navigation

I have got a strange memory leak on samsung devices. If I do a lot of navigations then it produces an OutOfMemoryException with this StackTrace:
Exception: Failed to allocate a 276060 byte allocation with 184864 free bytes and 180KB until OOM
StackTrace:
--- End of managed Java.Lang.OutOfMemoryError stack trace ---
java.lang.OutOfMemoryError: Failed to allocate a 276060 byte allocation with 184864 free bytes and 180KB until OOM
**at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:977)
at android.graphics.Bitmap.createBitmap(Bitmap.java:948)
at android.graphics.Bitmap.createBitmap(Bitmap.java:915)
at android.widget.TextView$MagnifierView.getContentsBitmap(TextView.java:14862)
at android.widget.TextView$MagnifierView.<init>(TextView.java:14806)
at android.widget.TextView.getMagnifierView(TextView.java:14707)**
at android.widget.Editor.onDetachedFromWindow(Editor.java:469)
at android.widget.TextView.onDetachedFromWindowInternal(TextView.java:6224)
at android.view.View.dispatchDetachedFromWindow(View.java:16766)
at android.view.ViewGroup.removeAllViewsInLayout(ViewGroup.java:5154)
at md58b29b5ebe7ec5add1ba4eaa7f6c6bb96.EventDetailsView_1.n_onDestroy(Native Method)
at md58b29b5ebe7ec5add1ba4eaa7f6c6bb96.EventDetailsView_1.onDestroy(EventDetailsView_1.java:47)
at android.app.Activity.performDestroy(Activity.java:7210)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1161)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4621)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4661)
at android.app.ActivityThread.-wrap7(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1703)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6776)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
Does anybody have an idea what these lines (See below) do and why the hell it allocates memory (Bitmap) when it is being destroyed?
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.Bitmap.nativeCreate(Native Method)
at android.graphics.Bitmap.createBitmap(Bitmap.java:977)
at android.graphics.Bitmap.createBitmap(Bitmap.java:948)
at android.graphics.Bitmap.createBitmap(Bitmap.java:915)
at android.widget.TextView$MagnifierView.getContentsBitmap(TextView.java:14862)
at android.widget.TextView$MagnifierView.<init>(TextView.java:14806)
at android.widget.TextView.getMagnifierView(TextView.java:14707)**
As far I understand from my testing, the activities are kept in memory even after OnDestroyed or Finish are called. If I navigate back and wait a minute I see the free memory is climbing again. Otherwise, the allocated memory get's bigger and at some point there is not enough space to do another navigation so the system tries to free memory by destroying an old activity. But this activity is allocating memory (MagnifierView) which isn't free during the Destroy-Process.
When I do the same on a Xperia Z5, the memory is freed right after a back navigation.

StaticLayout OutOfMemoryError with large text

I get error when I use StaticLayout for create pagination of large text (~6mb).
This is my log:
java.lang.OutOfMemoryError
at android.text.MeasuredText.addStyleRun(MeasuredText.java:193)
at android.text.MeasuredText.addStyleRun(MeasuredText.java:269)
at android.text.StaticLayout.generate(StaticLayout.java:291)
at android.text.StaticLayout.<init>(StaticLayout.java:143)
at android.text.StaticLayout.<init>(StaticLayout.java:93)
at android.text.StaticLayout.<init>(StaticLayout.java:71)
at android.text.StaticLayout.<init>(StaticLayout.java:51)
at com.ex.test.pagenation.Pagination.layout(Pagination.java:38)
at com.ex.test.pagenation.Pagination.<init>(Pagination.java:34)
at com.ex.test.pagenation.MainActivity$1.onGlobalLayout(MainActivity.java:51)
at android.view.ViewTreeObserver.dispatchOnGlobalLayout(ViewTreeObserver.java:847)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2006)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1200)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6401)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:573)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5335)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Is there any suggestion for fix this error? Or Is there any alternative solution?
You should rewrite or extend Pagination class.
You should not put all the text into StaticLayout at once.
Instead, you should split text into parts. Parts should not be too lage.
I guess 10k-100k will be ok.
take first part, split it into pages, count pages, multiply it by amount of parts - that will be approximate quantity of pages in you book.
When a user want to see the past page of a first part, you should start second part just where the last page of first part begins. And so on.
Do not load all the text into StaticLayout - it is too much.

Android throwing out of memory error when trying to load 1 megabyte image

The relevant code:
runOnUiThread(new Runnable() {
#Override
public void run() {
ImageButton btn = (ImageButton) findViewById(R.id.info_image);
btn.setImageResource(currentID[currentIDPos]);
}
});
It's saying that the run method is making a 400-some megabyte allocation. My jpgs are no more than a megabyte in size. The run() method is called on a timer every 3-4 seconds or so and on click, but that shouldn't matter because from what I can tell using printlns the run() is only called once before the crash.
Edit: Here's the exception. Had to run it again to get this, it's a different amount of memory this time but still very large.
FATAL EXCEPTION: main
Process: com.grey.handsaver, PID: 32531
java.lang.OutOfMemoryError: Failed to allocate a 215151564 byte allocation with 33554400 free bytes and 100MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:988)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2580)
at android.content.res.Resources.loadDrawable(Resources.java:2487)
at android.content.res.Resources.getDrawable(Resources.java:814)
at android.content.res.XResources.getDrawable(XResources.java:572)
at android.content.Context.getDrawable(Context.java:403)
at android.widget.ImageView.resolveUri(ImageView.java:747)
at android.widget.ImageView.setImageResource(ImageView.java:398)
at com.grey.handsaver.ExerciseInfoActivity$3.run(ExerciseInfoActivity.java:128)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5430)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:913)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:706)
at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:115)
Try to use picasso library for loading large image.it's having inbuilt cache functionality.
Step 1:
First write follow code in gradle.build and sync gradle.
compile 'com.squareup.picasso:picasso:2.5.2'
Step 2:
Picasso.with(context).load("YOUR IMAGE PATH").into(btn);
and write above code where we load the image.in this code you must need to provide image path and make sure image path is valid.if you really want to learn something more about this Library than please Visit this.
I hope your are clear with my Idea.
Best of Luck
Most likely the issue is that you are not clearing up the previously allocated space. Are you sure that the fragment/activity that loads these pictures is also removed from backstack? Or maybe the images themselves are not being garbage collected?
Re-do the same steps that are causing the OutofMemory Exception but make sure to switch to Memory Monitor Tab in Android Studio and check where the Memory is increasing drastically but not being freed when it should be. This should give you a head start to see where the memory leak might be.
Also possible that there is no leak, rather your pictures themselves are huge (although doesnt seems to be). In this case you should do lazy loading, cache implementation etc. or just use some third party library like Picasso which handle this for you
Alright, I figured it out. I'm using an lg g4, which uses xxxhdpi, and my images were in the drawable folder, not the drawable-xxxhdpi folder. This solved my problem without using picasso or the other methods.

Out of Memory Error while loading bitmaps

i have an android app with 3 acitivtys:
A1 --starts--> A2 --starts--> A3 --when finished his process: starts--> A1
(so i don't "finish();" an app. i start the next activitys with "startActivity(..);" the whole time after userinteraction)
so there is a loop in these 3 activitys.
On each Activity, i display 3-9 pictures, located on the SD-card, which i load with my following function:
try
{
Uri selectedImageURI = Uri.parse(strImagePath);
File imgFile = new File(getRealPathFromURI(selectedImageURI, c));
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ivTmp.setImageBitmap(myBitmap);
}catch (Exception e)
{
return null;
}
This all works.
But sometimes (after looping a few times through my activitys), my app crashes..
Logcat tells me:
01-16 13:42:15.863: DEBUG/dalvikvm(23161): GC_BEFORE_OOM freed 10K, 9% free 59019K/64400K, paused 29ms, total 30ms
01-16 13:42:15.863: ERROR/dalvikvm-heap(23161): Out of memory on a 8018704-byte allocation.
01-16 13:42:15.863: ERROR/AndroidRuntime(23161): FATAL EXCEPTION: main
java.lang.OutOfMemoryError
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:502)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:355)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:785)
at android.content.res.Resources.loadDrawable(Resources.java:1965)
at android.content.res.Resources.getDrawable(Resources.java:660)
at android.widget.ImageView.resolveUri(ImageView.java:616)
at android.widget.ImageView.setImageResource(ImageView.java:349)
at <MyApp>.MyActivity$6.run(MyActivity.java:143)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
Someone can give my some tips how to handle the crashes?
Maybe its because my activitys are set to state "paused" instead of closing them correctly?
for quick fix you can add
android:largeHeap="true" in your manifest application tag
link here:
I face OOM problem for my table in kindle and nook
Heap size (large)
android:largeHeap="true"
there specification is mentioned to use larger heap link here:
edit: use Caching Bitmaps technique link here
I had the similar problem while displaying high resolution images. I have searched and applied all the android bitmap solutions given in http://developer.android.com/training/displaying-bitmaps/index.html and the following caches mekanism in the link. but none of them work. not any right solution anywhere. Then I figured out that the problem is : I couldnt use the drawable folder structure right. I was keeping high resolution images in mdpi and hdpi folders . this cause android scale up the images to the ultra sizes. 100 kb image was causing 20 mb increase in memory thanks to the android monitor / memory section.
so I have added these ultra resolution images to xxhdpi folder , then It was FIXED suddenly. then my image slider work flawlessly
Yeah android doesnt immediately destroy activities when they are not visible to the user, but there are a number of lifecycle methods that are called depending on the current state. Check out http://developer.android.com/guide/components/activities.html#Lifecycle
You could try finishing the activities in onStop() or onDestroy() as these will be called when the activity is not visible and when the system runs low on memory respectively. :-)
This is due to the high resolution of image you have to scaling the bitmap use the following code
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
int h = 100; // height in pixels
int w = 100; // width in pixels
Bitmap photoBitMap = Bitmap.createScaledBitmap(myBitmap,h, w, true);
ivTmp.setImageBitmap(photoBitMap);

Displayed resolution density of drawables halving on each program start

I've got an Android app that uses both drawables from its own resources folder and from the resources folder of a package linked via shared user id.
I'm facing a decrease of the drawables' pixel density (resulting in interpolation artefacts) of only own resources** each time the app is run, while those linked*** appear normal.
Executing the app about the 10th time, it crashes*.
Then loading for the 1st time displays all images in their original density.
The app is based on SDK version 1.6 and no specific density dependent resources, meaning strictly designed for 320 x 480px.
The issue does appear neither on a device with a display size matching as above, nor in an emulator with both matching and larger display size. In the last case the images are correctly scaled to fit.
I don't know where (in the code) to start looking for the reasons of that bug.
Thanks in advance for any hints!
EDIT:
I should also mention that several Dialogs (e.g. ProgressDialog) are drawn in half the size as before when reloading the application.
* Log output when the app crashes:
ERROR/AndroidRuntime(23632): FATAL EXCEPTION: main
ERROR/AndroidRuntime(23632): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.myapp/com.myapp.Paketliste}: android.view.InflateException: Binary XML file line #20: Error inflating class <unknown>
ERROR/AndroidRuntime(23632): Caused by: android.view.InflateException: Binary XML file line #20: Error inflating class <unknown>
ERROR/AndroidRuntime(23632): Caused by: java.lang.reflect.InvocationTargetException
ERROR/AndroidRuntime(23632): Caused by: android.content.res.Resources$NotFoundException: File res/drawable/buttons.png from drawable resource ID #0x7f020016
ERROR/AndroidRuntime(23632): Caused by: java.lang.IllegalArgumentException: width and height must be > 0
WARN/ActivityManager(2461): Force finishing activity com.myapp/.Paketliste
* * The image loaded by these lines appears as described above:
ImageView imageView_IconOfAnotherPackage = (ImageView) row
.findViewById(R.id.paketliste_installed);
imageView_IconOfAnotherPackage
.setImageResource(R.drawable.default_icon);
* * * Loading an image which appears WITHOUT AN ISSUE:
imageView_IconOfAnotherPackage
.setImageDrawable(this
.getPackageManager()
.getResourcesForApplication('com.myotherapp')
.getDrawable(0x7f020001)
);
I found a post where a guy presumably was having the same problem (and found a solution) here:
http://adrianvintu.com/blogengine/post/Force-Locale-on-Android.aspx
(via this answer: Set-up the application Language in Android Preferences)

Categories

Resources