You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:20:55