Out of Memory : android.support.v7.app.AppCompatActivity.onCreate - android

we recently switched to using AppCompatActivity instead of FragmentActivity and now some devices are randomly crashing with the following error. No idea why this is happening.
Fatal Exception: java.lang.OutOfMemoryError: Failed to allocate a 16008012 byte allocation with 4277152 free bytes and 4MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(VMRuntime.java)
at android.graphics.BitmapFactory.nativeDecodeAsset(BitmapFactory.java)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:856)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:675)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:703)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:733)
at android.graphics.drawable.BitmapDrawable.updateStateFromTypedArray(BitmapDrawable.java:779)
at android.graphics.drawable.BitmapDrawable.inflate(BitmapDrawable.java:741)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:2549)
at android.graphics.drawable.LayerDrawable.inflateLayers(LayerDrawable.java:254)
at android.graphics.drawable.LayerDrawable.inflate(LayerDrawable.java:164)
at android.graphics.drawable.Drawable.createFromXmlInner(Drawable.java:2549)
at android.graphics.drawable.Drawable.createFromXml(Drawable.java:2320)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:4210)
at android.content.res.Resources.loadDrawable(Resources.java:4089)
at android.content.res.Resources.getDrawable(Resources.java:2005)
at android.content.res.Resources.getDrawable(Resources.java:1987)
at android.content.Context.getDrawable(Context.java:464)
at android.support.v4.content.ContextCompat.android.support.v4.content.ContextCompatApi21.getDrawable(SourceFile:3026)
at android.support.v7.widget.AppCompatDrawableManager.getDrawable(SourceFile:200)
at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(SourceFile:81)
at android.support.v7.app.AppCompatDelegateImplBase.(SourceFile:127)
at android.support.v7.app.AppCompatDelegateImplV9.(SourceFile:147)
at android.support.v7.app.AppCompatDelegateImplV11.(SourceFile:27)
at android.support.v7.app.AppCompatDelegateImplV14.(SourceFile:53)
at android.support.v7.app.AppCompatDelegateImplV23.(SourceFile:29)
at android.support.v7.app.AppCompatDelegate.create(SourceFile:203)
at android.support.v7.app.AppCompatDelegate.create(SourceFile:185)
at android.support.v7.app.AppCompatActivity.getDelegate(SourceFile:525)
at android.support.v7.app.AppCompatActivity.onCreate(SourceFile:74)
at com.dubizzle.horizontal.activities.AbstractActivity.onCreate(SourceFile:98)
at com.dubizzle.horizontal.activities.ItemPhotoViewer.onCreate(SourceFile:68)
at android.app.Activity.performCreate(Activity.java:6876)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1135)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3207)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3350)
at android.app.ActivityThread.access$1100(ActivityThread.java:222)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7229)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

You are trying to load an image using the BitmapFactory right?
I assume that your image is too big:
16008012 byte allocation with 4277152 free bytes and 4MB until OOM
Your image is 16008012 but you only have 4277152 bytes free.
Try using a smaller image.

This happened to me when I set a rather large drawable as the windowBackground property of the activity's theme. Reducing the size of the image should fix it

Related

How can I solve OutOfMemory issue with Lottie and ViewPager in Jetpack Compose?

I am using lottie compose with ViewPager.
val composition by rememberLottieComposition(LottieCompositionSpec.Asset(tutorial.lottieSrc))
val progress by animateLottieCompositionAsState(composition)
val lottieAnimatable = rememberLottieAnimatable()
LaunchedEffect(Unit) {
lottieAnimatable.animate(
composition,
iteration = LottieConstants.IterateForever
)
}
LottieAnimation(
composition = composition,
progress = { progress },
modifier = Modifier
.size(220.dp)
)
This causes OutOfMemory.
Each page uses lottie and the average size is around 4MB.
I think it's not that big size. But my guess is, since it's viewpager, it loads duplicate lottile on the memory.
I get this error:
Clamp target GC heap from 51MB to 48MB
And then when the app crashes.
java.lang.OutOfMemoryError: Failed to allocate a 12 byte allocation with 0 free bytes and -16B until OOM
at androidx.compose.runtime.CompositionImpl.addPendingInvalidationsLocked(Composition.kt:674)
at androidx.compose.runtime.CompositionImpl.drainPendingModificationsLocked(Composition.kt:566)
at androidx.compose.runtime.CompositionImpl.recordModificationsOf(Composition.kt:656)
at androidx.compose.runtime.Recomposer.recordComposerModificationsLocked(Recomposer.kt:417)
at androidx.compose.runtime.Recomposer.access$recordComposerModificationsLocked(Recomposer.kt:125)
at androidx.compose.runtime.Recomposer$runRecomposeAndApplyChanges$2.invokeSuspend(Recomposer.kt:499)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.runtime.PausableMonotonicFrameClock#b1d76ac, androidx.compose.ui.platform.MotionDurationScaleImpl#abc1f75, StandaloneCoroutine{Cancelling}#d2d3b0a, AndroidUiDispatcher#7fb5f7b]
Is there any solution for this?
Referes:
https://google.github.io/accompanist/pager/
https://github.com/airbnb/lottie/blob/master/android-compose.md

Notification/Service - Could not copy bitmap to parcel blob

In my app I start a foreground service and create a notification for it:
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId);
...
builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.icon));
...
This throws an exception on one of my users devices like below (a java.lang.RuntimeException: Could not copy bitmap to parcel blob. exception).
My icons do have default dimensions and small sizes, don't know why they make problems on one device.
Does anyone know what the real issue could be? And how I could avoid this issue or gracefully handle this case? Seems to be a memory issue.
Mipmap icon
I have included following icons:
mdpi (48x48, 3,51kB)
hdpi (72x72, 6,65kB)
xhdpi (96x96, 9,08kB)
xxhdpi (144x144, 17,2kB)
xxxhdpi (192x192, 22,0kB)
Exception
java.lang.RuntimeException: Unable to start service com.my.app.services.OverlayService#ea0edcc with Intent { act=RESUME cmp=com.my.app/.services.OverlayService }: java.lang.RuntimeException: Could not copy bitmap to parcel blob.
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3079)
at android.app.ActivityThread.access$2200(ActivityThread.java:163)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1460)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5585)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: java.lang.RuntimeException: Could not copy bitmap to parcel blob.
at android.graphics.Bitmap.nativeWriteToParcel(Native Method)
at android.graphics.Bitmap.writeToParcel(Bitmap.java:1541)
at android.graphics.drawable.Icon.writeToParcel(Icon.java:705)
at android.os.Parcel.writeParcelable(Parcel.java:1437)
at android.os.Parcel.writeValue(Parcel.java:1343)
at android.os.Parcel.writeArrayMapInternal(Parcel.java:686)
at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
at android.os.Bundle.writeToParcel(Bundle.java:1079)
at android.os.Parcel.writeBundle(Parcel.java:711)
at android.app.Notification.writeToParcel(Notification.java:1731)
at android.app.INotificationManager$Stub$Proxy.enqueueNotificationWithTag(INotificationManager.java:701)
at android.app.NotificationManager.notify(NotificationManager.java:230)
at android.app.NotificationManager.notify(NotificationManager.java:194)
at com.my.app.services.BaseOverlayService.a(SourceFile:39)
at com.my.app.services.BaseOverlayService.a(SourceFile:23)
at com.my.app.services.OverlayService.onStartCommand(SourceFile:136)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3062)

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.

why android asks for a huge memory allocation for a small photo?

I am trying to load a jpeg photo with a size of 965KB on my android phone. The code is below. When I run the code, the app crashes.
Button _btn = (Button) findViewById(R.id.btn1);
_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Drawable _draw = getResources().getDrawable(R.drawable.sea, null);
}
});
This is the crash log.
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.a3sumatch.multipart, PID: 29240
java.lang.OutOfMemoryError: Failed to allocate a 362797068 byte
allocation with 8388608 free bytes and 254MB 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:1080)
at
android.content.res.Resources.loadDrawableForCookie(Resources.java:2761)
at android.content.res.Resources.loadDrawable(Resources.java:2654)
at android.content.res.Resources.getDrawable(Resources.java:833)
at
com.a3sumatch.multipart.MainActivity$1.onClick(MainActivity.java:40)
at android.view.View.performClick(View.java:5205)
at android.view.View$PerformClick.run(View.java:21176)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:171)
at android.app.ActivityThread.main(ActivityThread.java:5611)
at java.lang.reflect.Method.invoke(Native Method)
at
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
I am trying to load a jpeg photo with a size of 965KB on my android phone
That is an absolutely massive photo. JPEG, like PNG and WebP, is a compressed file format. To put that in perspective, a 3229x2480 photo of my balding head is 829.3KB in a JPEG. I would expect yours to be a bit larger in each dimension. That resolution is higher than the resolution of any Android device screen that I know of.
Your OutOfMemoryError is for a 362797068-byte allocation. A Bitmap is an uncompressed version of the image. 362797068 bytes is equivalent to about a 9524x9524 square image (and 4 bytes/pixel).
So, you need to do two things:
If you have this image in res/drawable/, move it to res/drawable-nodpi/
Reduce the resolution of this image by at least a factor of four along each dimension

java.lang.OutOfMemoryError: Failed to allocate a 756946956 byte allocation with 16777216 free bytes and 433MB until OOM

I want to change the background image of my Activity's layout every time I launch that activity. For that reason, inside onResume(), I am randomly setting the background image of layout like this:
#Override
public void onResume(){
super.onResume();
Random r = new Random();
int randNumber = r.nextInt(homeBackgroundImage.length);
mBackgroundLayout.setBackground(ResourcesCompat.getDrawable(getResources(), homeBackgroundImage[randNumber], null));
}
But, I am getting exception in the following line:
mBackgroundLayout.setBackground(ResourcesCompat.getDrawable(getResources(), homeBackgroundImage[randNumber], null));
This is the logcat output:
java.lang.OutOfMemoryError: Failed to allocate a 756946956 byte allocation with 16777216 free bytes and 433MB 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:1080)
at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635)
at android.content.res.Resources.loadDrawable(Resources.java:2540)
at android.content.res.Resources.getDrawable(Resources.java:806)
at android.support.v4.content.res.ResourcesCompatApi21.getDrawable(ResourcesCompatApi21.java:27)
at android.support.v4.content.res.ResourcesCompat.getDrawable(ResourcesCompat.java:60)
at in.avara.app.avaravrplayer.Activity.MainActivity.onResume(MainActivity.java:167)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
at android.app.Activity.performResume(Activity.java:6327)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3092)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3134)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2481)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Someone, please suggest me What is the optimized and best way to change background image of a layout randomly on every launch.
NOTE: I have already tried adding android:hardwareAccelerated="false" , android:largeHeap="true". But, it didn't work in my case.
Thanks in advance!
You are attempting to allocate 756946956 bytes ~= 721MB. This is much too large.
Moreover, 756946956 bytes represents the equivalent of a 13756 x 13756 pixel image. This is far larger than any Android screen.
You need to identify the image that is failing and reduce its resolution significantly.
If you put this image in res/drawable/, bear in mind that res/drawable/ is a synonym of res/drawable-mdpi/. Your image will be upsampled when you use that drawable on higher screen densities (e.g., xhdpi). You probably should move that drawable out of res/drawable/ and into either a density-specific directory for the desired density (e.g., res/drawable-xhdpi/), or into res/drawable-nodpi/ to disable this density-based resampling.
Try to put move your images from res/drawable/ to res/drawable/drawable-nodpi. If problem is still here, in your manifest under application put android:largeHeap="true".

Categories

Resources