RemoteViews是一個可序列化的視圖描述對象,包含佈局資源 ID 與一組修改操作(setText、setImageViewResource、setOnClickPendingIntent 等)。它允許進程 A 構建 UI 描述,進程 B(系統進程/Launcher)解析並渲染顯示。
| 場景 | 宿主進程 | 典型用法 |
|---|---|---|
| 自定義通知 | SystemUI (NotificationShade) | NotificationCompat.Builder.setCustomContentView(remoteViews) |
| 桌面 Widget (AppWidget) | Launcher (系統/第三方) | AppWidgetManager.updateAppWidget(id, remoteViews) |
| 彈窗/權限對話框 | SystemUI | 媒體播放控制、來電界面 |
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);
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);
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) 反射調用,受限)。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 限制、性能邊界,是開發豐富通知、桌面組件的前提。