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的工作原理

通知栏和桌面小部件分别由NotificationManagerAppWidgeManager管理。

NotificationManager通过BinderSystemServer进程中的NotificationManagerService进行通信;

AppWidgetManager通过BinderSystemServer进程中的AppWidgetService进行通信。

由此可见,这构成了跨进程通信的场景。

Android系统并没有通过Binder去直接支持View的跨进程访问,而是提供了一个Action的概念,Action代表一个View操作,Action也实现了Parcelable接口。RemoteViews的内部机制如下图所示。

RemoteViews的作用和工作原理_第1张图片
RemoteViews.png

系统首先将View操作封装到Action对象,并将这些对象跨进程传输到远程进程,接着在远程进程中,依次执行Action对象中的具体操作。

远程进程通过RemoteViews的apply方法来进行View的更新操作,RemoteViews的apply方法内部则会去遍历所有的Action对象,并调用它们的apply方法,具体的View更新操作是由Action对象的apply方法来完成的。

这种做法的好处是:

(1)不需要定义大量的Binder接口。

(2)通过在远程进程批量执行RemoteViews的修改操作,从而避免大量的IPC操作,提高程序的性能。

参考

任玉刚的《Android开发艺术探索》

你可能感兴趣的:(RemoteViews的作用和工作原理)