首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Android RemoteViews 詳解:用於通知欄、桌面組件的跨進程 UI 渲染

     編輯:程式設計綜合問答

核心定義

RemoteViews 是一個可序列化的視圖描述對象,包含佈局資源 ID 與一組修改操作(setText、setImageViewResource、setOnClickPendingIntent 等)。它允許進程 A 構建 UI 描述,進程 B(系統進程/Launcher)解析並渲染顯示。

主要應用場景

場景宿主進程典型用法
自定義通知 SystemUI (NotificationShade) NotificationCompat.Builder.setCustomContentView(remoteViews)
桌面 Widget (AppWidget) Launcher (系統/第三方) AppWidgetManager.updateAppWidget(id, remoteViews)
彈窗/權限對話框 SystemUI 媒體播放控制、來電界面

核心 API 與代碼示例

1. 構建 RemoteViews

RemoteViews rv = new RemoteViews(getPackageName(), R.layout.custom_notification);
rv.setTextViewText(R.id.title, "新消息");
rv.setTextViewText(R.id.content, "您有一條重要通知");
rv.setImageViewResource(R.id.icon, R.drawable.ic_message);

// 點擊事件:必須用 PendingIntent
Intent clickIntent = new Intent(this, MainActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, clickIntent, PendingIntent.FLAG_IMMUTABLE);
rv.setOnClickPendingIntent(R.id.root_layout, pi);

2. 列表型 RemoteViews (API 21+)

RemoteViews rv = new RemoteViews(getPackageName(), R.layout.notification_list);
rv.setRemoteAdapter(R.id.list_view, new Intent(this, ListWidgetService.class));
rv.setEmptyView(R.id.list_view, R.id.empty_view);

3. 進階:集合操作與條件判斷 (API 31+)

rv.addView(R.id.container, childView);
rv.removeAllViews(R.id.container);
rv.setViewVisibility(R.id.badge, View.VISIBLE);

限制與注意事項(必讀)

  • 僅支持部分佈局/控件:LinearLayout, RelativeLayout, FrameLayout, GridLayout, TextView, ImageView, Button, ProgressBar, Chronometer, ListView, GridView, StackView, AdapterViewFlipper。不支持 ConstraintLayout, RecyclerView, WebView, 自定義 View。
  • 不支持任意方法調用:只能用 setXxx 系列預定義方法,無法調用 view.setBackgroundColor() 等(需用 setInt(R.id.view, "setBackgroundColor", color) 反射調用,受限)。
  • 跨進程序列化開銷:佈局過大、更新頻率高會導致 ANR 或 Binder 事務緩衝區溢出。建議佈局層級 ≤ 10,更新間隔 ≥ 1s。
  • PendingIntent 安全性:Android 12+ 必須顯式指定 FLAG_IMMUTABLE 或 FLAG_MUTABLE。

最佳實踐模板

public class NotificationHelper {
    public static void showCustomNotification(Context ctx, String title, String body) {
        RemoteViews collapsed = new RemoteViews(ctx.getPackageName(), R.layout.notif_collapsed);
        collapsed.setTextViewText(R.id.tv_title, title);
        collapsed.setTextViewText(R.id.tv_body, body);

        RemoteViews expanded = new RemoteViews(ctx.getPackageName(), R.layout.notif_expanded);
        expanded.setTextViewText(R.id.tv_title, title);
        expanded.setTextViewText(R.id.tv_body, body);
        expanded.setImageViewResource(R.id.iv_icon, R.drawable.ic_launcher);

        Intent intent = new Intent(ctx, MainActivity.class);
        PendingIntent pi = PendingIntent.getActivity(ctx, 0, intent, PendingIntent.FLAG_IMMUTABLE);

        NotificationCompat.Builder builder = new NotificationCompat.Builder(ctx, CHANNEL_ID)
            .setSmallIcon(R.drawable.ic_stat_icon)
            .setCustomContentView(collapsed)
            .setCustomBigContentView(expanded)
            .setContentIntent(pi)
            .setAutoCancel(true)
            .setPriority(NotificationCompat.PRIORITY_HIGH);

        NotificationManagerCompat.from(ctx).notify(NOTIF_ID, builder.build());
    }
}

總結

RemoteViews 是 Android「跨進程 UI」的基石,核心思想是序列化視圖描述而非傳遞 View 對象。掌握其支持的控件集合、API 限制、性能邊界,是開發豐富通知、桌面組件的前提。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved