自定义RemoteViews通知加载多张图片失败问题求助
Android自定义通知多ImageView显示异常问题
问题现象
创建包含4个ImageView的自定义通知时,仅设置1张图片能正常显示,设置2张及以上时通知无任何内容显示。
相关代码
通知创建函数
private void createNotification() { Intent intent = new Intent(this, RateDia.class); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE); RemoteViews layoutNotificacio = new RemoteViews(getPackageName(), R.layout.notificacio_gran); layoutNotificacio.setImageViewBitmap(R.id.imatge1, BitmapFactory.decodeResource(getResources(), R.drawable.e01_grinning_face)); layoutNotificacio.setImageViewBitmap(R.id.imatge2, BitmapFactory.decodeResource(getResources(), R.drawable.e02_grimacing_face)); layoutNotificacio.setImageViewBitmap(R.id.imatge3, BitmapFactory.decodeResource(getResources(), R.drawable.e03_grinning_face_with_smiling_eyes)); layoutNotificacio.setImageViewBitmap(R.id.imatge4, BitmapFactory.decodeResource(getResources(), R.drawable.e04_face_with_tears_of_joy)); NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.mimismo_icono_notificacio) .setContentTitle("Notificación de miMismo") .setCustomBigContentView(layoutNotificacio) .setPriority(NotificationCompat.PRIORITY_HIGH) .setContentIntent(pendingIntent) .setAutoCancel(true); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { notificationManager.notify(NOTIFICATION_ID, builder.build()); } }
RemoteView布局文件(notificacio_gran.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <ImageView android:id="@+id/imatge1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:adjustViewBounds="true" android:maxWidth="50dp" android:src="@drawable/e01_grinning_face" /> <ImageView android:id="@+id/imatge2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:adjustViewBounds="true" android:maxWidth="50dp" android:src="@drawable/e02_grimacing_face" /> <ImageView android:id="@+id/imatge3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:adjustViewBounds="true" android:maxWidth="50dp" android:src="@drawable/e04_face_with_tears_of_joy" /> <ImageView android:id="@+id/imatge4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:adjustViewBounds="true" android:maxWidth="50dp" android:src="@android:drawable/ic_menu_add" /> </LinearLayout>
问题分析
核心原因是RemoteViews加载的Bitmap总内存超限:直接用BitmapFactory.decodeResource加载原始尺寸图片,多图叠加后内存占用超过系统允许的通知布局阈值,导致系统直接丢弃整个自定义布局,表现为通知无内容。
解决方案
方案1:替换为setImageViewResource(优先推荐)
如果只是替换资源图片,不需要动态修改Bitmap内容,直接使用setImageViewResource更高效,避免Bitmap解码的内存问题:
layoutNotificacio.setImageViewResource(R.id.imatge1, R.drawable.e01_grinning_face); layoutNotificacio.setImageViewResource(R.id.imatge2, R.drawable.e02_grimacing_face); layoutNotificacio.setImageViewResource(R.id.imatge3, R.drawable.e03_grinning_face_with_smiling_eyes); layoutNotificacio.setImageViewResource(R.id.imatge4, R.drawable.e04_face_with_tears_of_joy);
方案2:对Bitmap进行缩放处理
如果必须使用动态Bitmap(比如需要修改图片内容),根据ImageView的maxWidth(50dp)缩放图片,减少内存占用:
private Bitmap getScaledBitmap(int drawableResId) { Resources res = getResources(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, drawableResId, options); // 计算缩放比例,目标宽度为50dp int targetWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50, res.getDisplayMetrics()); int scaleFactor = Math.max(1, options.outWidth / targetWidth); options.inJustDecodeBounds = false; options.inSampleSize = scaleFactor; return BitmapFactory.decodeResource(res, drawableResId, options); }
然后修改设置Bitmap的代码:
layoutNotificacio.setImageViewBitmap(R.id.imatge1, getScaledBitmap(R.drawable.e01_grinning_face)); layoutNotificacio.setImageViewBitmap(R.id.imatge2, getScaledBitmap(R.drawable.e02_grimacing_face)); layoutNotificacio.setImageViewBitmap(R.id.imatge3, getScaledBitmap(R.drawable.e03_grinning_face_with_smiling_eyes)); layoutNotificacio.setImageViewBitmap(R.id.imatge4, getScaledBitmap(R.drawable.e04_face_with_tears_of_joy));
方案3:补充普通自定义布局(可选)
如果希望通知在未展开状态也有内容,同时设置setCustomContentView(可复用同一布局):
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) // ... 其他配置 .setCustomContentView(layoutNotificacio) .setCustomBigContentView(layoutNotificacio) // ... 其他配置
验证建议
- 先测试方案1,若解决问题则说明是Bitmap解码内存导致的异常;
- 若必须使用动态Bitmap,再采用方案2;
- 可通过Logcat查看
RemoteViews相关警告/错误日志,确认是否为内存超限导致布局加载失败。
内容的提问来源于stack exchange,提问作者baku9953
相关产品推荐
相关产品推荐

