RemoteViews的作用和工作原理
RemoteViews的作用
RemoteViews表示的是一个View结构,它可以在其他进程中显示,由于它在其他进程中显示,为了能够更新它的界面,RemoteViews提供了一组基础的操作用于跨进程更新它的界面。简而言之,RemoteViews的作用是在其他进程中显示并更新View界面。
RemoteViews在Android中的使用场景有两种:通知栏和桌面小部件
1、在通知栏上的应用
通知栏的通知一般用系统默认提供的布局,如果要用自定义的布局,则可以用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的工作原理
通知栏和桌面小部件分别由NotificationManager
和AppWidgeManager
管理。
NotificationManager
通过Binder
和SystemServer
进程中的NotificationManagerService
进行通信;
AppWidgetManager
通过Binder
和SystemServer
进程中的AppWidgetService
进行通信。
由此可见,这构成了跨进程通信的场景。
Android系统并没有通过Binder
去直接支持View的跨进程访问,而是提供了一个Action
的概念,Action
代表一个View操作,Action
也实现了Parcelable接口。RemoteViews的内部机制如下图所示。
系统首先将View操作封装到Action对象,并将这些对象跨进程传输到远程进程,接着在远程进程中,依次执行Action对象中的具体操作。
远程进程通过RemoteViews的apply
方法来进行View的更新操作,RemoteViews的apply
方法内部则会去遍历所有的Action对象,并调用它们的apply
方法,具体的View更新操作是由Action对象的apply
方法来完成的。
这种做法的好处是:
(1)不需要定义大量的Binder接口。
(2)通过在远程进程批量执行RemoteViews的修改操作,从而避免大量的IPC操作,提高程序的性能。
参考
任玉刚的《Android开发艺术探索》