Google Play每日崩溃:Bitmap已回收异常排查求助(MIUI环境)
Hey there, let's break down this tricky crash you're facing. First, let's lay out the key details clearly:
The Crash Stack Trace
java.lang.IllegalStateException: at android.graphics.Bitmap.checkRecycled (Bitmap.java:394) at android.graphics.Bitmap.writeToParcel (Bitmap.java:1599) at miui.security.ISecurityManager$Stub$Proxy.saveIcon (ISecurityManager.java:1505) at miui.security.SecurityManager.saveIcon (SecurityManager.java:275) at com.miui.internal.os.Native.invoke (Native.java) at miui.reflect.Method.invoke (Method.java:120) at miui.content.res.ThemeRuntimeManager.saveIconInner (ThemeRuntimeManager.java:185) at miui.content.res.ThemeRuntimeManager.-wrap1 (SourceFile) at miui.content.res.ThemeRuntimeManager$ThemeServiceThread.run (ThemeRuntimeManager.java:159)
What's Actually Happening?
This is a MIUI-exclusive compatibility bug. The crash fires because MIUI's background system service (ThemeRuntimeManager) tries to serialize a Bitmap into a Parcel after that Bitmap has been recycled. Since you don't manually recycle Bitmaps or pass them via Intents, the issue stems from Picasso's automatic memory management:
Picasso aggressively recycles unused Bitmaps to free up RAM, but MIUI's service holds onto a reference to that Bitmap longer than expected. When Picasso recycles it, the system service attempts to use the dead Bitmap and hits the IllegalStateException.
How to Locate the Exact Trigger
Even though your code doesn't directly cause this, you can trace the root cause with these steps:
- Enable Picasso Debug Indicators: Add
Picasso.with(context).setIndicatorsEnabled(true)during app setup. This overlays small badges on ImageViews showing where the Bitmap came from (memory cache, disk cache, etc.). Watch for crashes when the badge indicates the Bitmap was recently evicted from memory cache. - Use Android Studio's Memory Profiler: Monitor Bitmap allocations and deallocations in real time. When the crash occurs, inspect the reference chain for the recycled Bitmap—you'll see MIUI's
ThemeServiceThreadholding onto it. - Test Without
.fit(): Your code uses.fit()to resize Bitmaps to match the ImageView. Try replacing it with a fixed size (e.g.,.resize(120, 120)) to rule out issues with resized Bitmaps being prematurely recycled.
Actionable Fixes to Try
Here are targeted solutions to resolve this MIUI-specific issue:
1. Copy the Bitmap Before Use
Create a deep copy of the Bitmap loaded by Picasso so MIUI's service uses the copy instead of the original (which Picasso might recycle):
Picasso.with(activity.getApplicationContext()) .load(IconRequestHandler.getUri(appsListItems.get(position).getPackageName())) .fit() .error(R.drawable.ic_default) .placeholder(R.drawable.ic_default) .into(new Target() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { // Create a copy to decouple from Picasso's memory management Bitmap safeBitmap = bitmap.copy(bitmap.getConfig(), true); holder.icon.setImageBitmap(safeBitmap); } @Override public void onBitmapFailed(Drawable errorDrawable) { holder.icon.setImageDrawable(errorDrawable); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { holder.icon.setImageDrawable(placeHolderDrawable); } });
Note: Keep a strong reference to the Target if using this in a RecyclerView to avoid garbage collection issues.
2. Adjust Picasso's Memory Policy (Debug Only)
Temporarily disable Picasso's memory caching to confirm it's the trigger (not recommended for production):
Picasso.with(activity.getApplicationContext()) .load(IconRequestHandler.getUri(appsListItems.get(position).getPackageName())) .fit() .memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE) .error(R.drawable.ic_default) .placeholder(R.drawable.ic_default) .into(holder.icon);
If the crash stops, you've confirmed Picasso's recycling is the issue—stick with solution #1 for production.
3. Check Your IconRequestHandler
If your handler returns a direct reference to a system-provided Bitmap (e.g., from PackageManager.getApplicationIcon()), MIUI might be trying to reuse that shared Bitmap. Modify the handler to return a copied Bitmap instead of the original system one.
Final Notes
This crash is unique to MIUI's custom system services—you won't see it on stock Android or other OEM skins. The core fix is breaking the link between Picasso's recyclable Bitmaps and MIUI's background service references.
内容的提问来源于stack exchange,提问作者Wakil Ahmad

