I have an app that works perfectly when run on my phone device. However, it crashes when run on the emulator.
2021-01-11 06:58:24.719 19783-19783/com.example.myapplication E/RecyclerView: No adapter attached; skipping layout
2021-01-11 06:58:35.827 19783-19783/com.example.myapplication E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 19783
java.lang.OutOfMemoryError: Failed to allocate a 599752036 byte allocation with 4194304 free bytes and 199MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:620)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:455)
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1155)
at android.content.res.ResourcesImpl.loadDrawableForCookie(ResourcesImpl.java:720)
at android.content.res.ResourcesImpl.loadDrawable(ResourcesImpl.java:571)
at android.content.res.Resources.loadDrawable(Resources.java:858)
at android.content.res.TypedArray.getDrawable(TypedArray.java:928)
at android.widget.ImageView.<init>(ImageView.java:162)
at android.widget.ImageView.<init>(ImageView.java:150)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:74)
at androidx.appcompat.widget.AppCompatImageView.<init>(AppCompatImageView.java:69)
at androidx.appcompat.app.AppCompatViewInflater.createImageView(AppCompatViewInflater.java:199)
at androidx.appcompat.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:119)
at androidx.appcompat.app.AppCompatDelegateImpl.createView(AppCompatDelegateImpl.java:1551)
at androidx.appcompat.app.AppCompatDelegateImpl.onCreateView(AppCompatDelegateImpl.java:1602)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:769)
at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:727)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:858)
at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:821)
at android.view.LayoutInflater.inflate(LayoutInflater.java:518)
at android.view.LayoutInflater.inflate(LayoutInflater.java:426)
at com.example.myapplication.Fragments.Friends_List$DisplayAllFriends$adapter$1.onCreateViewHolder(Friends_List.kt:495)
The problem is pointing to my friends list xml file but everything looks ok and runs fine on my actual phone..
Answered in the comments, but the issue is that it's trying to allocate memory for a 599MB bitmap, which is very huge! It's probably a very large image - 4000 x 4000 x 32 bits gets you into the ballpark. It might not be that large in filesize (JPG and PNG can be very efficient) but they unpack into a bitmap, and that memory use depends on the dimensions of the image.
You probably shouldn't be using images that size anyway (or if you are, you might need to look into more efficient ways of displaying them) - but from what it sounds like, you have a list of stuff, and the images should be fairly small. So you definitely don't want to be using huge ones!
Really, you need to work out how large the images should be on the screen (in dp
, same as every other View
is measured in, so it's easy to compare) and then resize them to the appropriate size in pixels. Here's a description of the different densities (with dp to pixel conversions - ideally you'll have a version for each density, resized perfectly and optimised (e.g. you might want to apply sharpening on the smaller ones)
It's not just about optimising the images for display either - constantly scaling large images will make your app run worse, and including resources that are way bigger than you actually need will bloat the APK / App Bundle size. So it's definitely good practice to have images that are exactly what you need!