RemoteViews的应用及原理

RemoteViews表示远程View,用于跨进程更新UI,主要用于系统通知栏(Notification)和桌面小部件(App Widget)中。

RemoteViews的应用

RemoteViews在实际开发中,主要用于给系统通知栏和桌面小部件更新界面。

在通知栏上显示通知是通过NotificationManager的notify()方法实现的,如果通知栏需要自定义布局,就需要使用到RemoteViews。

桌面小部件是通过AppWidgetProvider实现的,AppWidgetProvider本质上是一个广播,不过,小部件的界面需要使用RemoteViews实现。

之所以要在通知栏和小部件中使用RemoteViews展示界面,是因为它们的界面运行在其它进程中,即系统的SystemServer进程。因此,一个APP如果要更新通知栏和小部件的界面,就需要跨进程更新,普通View是不支持跨进程更新的,这时,就需要使用RemoteViews实现这样的需求。

RemoteViews在通知栏和小部件中的使用方法可以参考官方文档。

RemoteViews的原理

RemoteViews的作用是在其它进程中显示并更新UI,不过它只支持一些常用的Layout和View(具体参考官方文档)。因为是跨进程的,RemoteViews没有提供findViewById()方法,所以,无法直接访问它的View元素。不过,RemoteViews提供了一系列set方法去访问其View元素,比如设置资源、添加点击事件等。

RemoteViews主要用于通知栏和小部件中,通知栏和小部件分别由NotificationManager和AppWidgetManager管理,而NotificationManager和AppWidgetManager是通过Binder分别和SystemServer进程中的NotificationManagerService以及AppWidgetService进行通信的。因此,通知栏和小部件中的界面实际上是由NotificationManagerService以及AppWidgetService加载的,它们运行在系统SystemServer进程中,APP进程要更新RemoteViews,就需要使用Binder进行跨进程通信。

RemoteViews中的IPC过程如下:

  1. RemoteViews通过Binder传递到SystemServer进程,系统会根据RemoteViews的包名等信息得到相关的资源;
  2. 通过LayoutInflater加载RemoteViews的布局文件,在SystemServer进程中,这个布局文件其实是一个普通的View,不过相对于APP进程,它是一个RemoteViews;
  3. 系统对View执行界面初始化任务,这些操作是通过RemoteViews提供的一系列set方法提交的,不过,这些set方法对View的操作不是立即执行的,在RemoteViews内部会记录这些操作,具体执行要等到RemoteViews被加载后执行;
  4. 当APP进程需要更新RemoteViews时,需要调用相关的set方法,通过NotificationManager和AppWidgetManager来提交更新任务给SystemServer进程,具体更新操作需要在SystemServer进程中完成。
坚持原创技术分享,您的支持将鼓励我继续创作!