RemoteViews的作用和工作原理

RemoteViews的作用 RemoteViews表示的是一个View结构,它可以在其他进程中显示,由于它在其他进程中显示,为了能够更新它的界面,RemoteViews提供了一组基础的操作用于跨进程更新它的界面。简而言之,RemoteViews的作用是在其他进程中显示并更新View界面。
RemoteViews在Android中的使用场景有两种:通知栏和桌面小部件
1、在通知栏上的应用
【RemoteViews的作用和工作原理】通知栏的通知一般用系统默认提供的布局,如果要用自定义的布局,则可以用RemoteViews。使用如下:

RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.layout_notification); // 设置RemoteViews控件UI remoteViews.setTextViewText(R.id.msg, “test”); remoteViews.setImageViewResource(R.id.icon, R.drawable.icon1); // 设置RemoteViews点击事件 PendingIntent openActivity2PendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, DemoActivity2.class), PendingIntent.FLAG_UPDATE_CURRENT); remoteViews.setOnClickPendingIntent(R.id.open_activity2, openActivity2PendingIntent); // 初始化Notification的contentView Notification notification = new Notification(); notification.contentView = remoteViews;

这样就完成自定义通知的设置。
2、在桌面小部件的应用
桌面小部件不管是初始化界面还是后续的更新界面都必须使用RemoteViews来完成。使用如下:
// 窗口小部件更新,发送一个点击事件 private void onWidgetUpdate(Context context, AppWidgetManager appWidgeManger, int appWidgetId) {RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget); // "窗口小部件"点击事件发送的Intent广播 Intent intentClick = new Intent(); intentClick.setAction(CLICK_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); remoteViews.setOnClickPendingIntent(R.id.imageView1, pendingIntent); appWidgeManger.updateAppWidget(appWidgetId, remoteViews); }

RemoteViews的工作原理 通知栏和桌面小部件分别由NotificationManagerAppWidgeManager管理。
NotificationManager通过BinderSystemServer进程中的NotificationManagerService进行通信;
AppWidgetManager通过BinderSystemServer进程中的AppWidgetService进行通信。
由此可见,这构成了跨进程通信的场景。
Android系统并没有通过Binder去直接支持View的跨进程访问,而是提供了一个Action的概念,Action代表一个View操作,Action也实现了Parcelable接口。RemoteViews的内部机制如下图所示。
RemoteViews的作用和工作原理
文章图片
RemoteViews.png 系统首先将View操作封装到Action对象,并将这些对象跨进程传输到远程进程,接着在远程进程中,依次执行Action对象中的具体操作。
远程进程通过RemoteViews的apply方法来进行View的更新操作,RemoteViews的apply方法内部则会去遍历所有的Action对象,并调用它们的apply方法,具体的View更新操作是由Action对象的apply方法来完成的。
这种做法的好处是:
(1)不需要定义大量的Binder接口。
(2)通过在远程进程批量执行RemoteViews的修改操作,从而避免大量的IPC操作,提高程序的性能。
参考
任玉刚的《Android开发艺术探索》

    推荐阅读