Android进阶知识(十六):理解RemoteViews

Android进阶知识(十六):理解RemoteViews

一、RemoteViews及其应用

  RemoteViews表示的是一个View结构,一种远程View,它可以在其它进程中显示,由于它在其他进程中显示,为了能够更新它的界面,RemoteViews提供了一组基础的操作用于跨进程更新它的界面
  RemoteViews在Android中的使用场景有两种:通知栏和桌面小部件
  通知栏主要是通过NotificationManager的notify方法来实现,它除了默认效果外,还可以另外自定义布局(这就是RemoteView的应用)。桌面小部件则是通过AppWidgetProvider来实现的,AppWidgetProvider本质上是一个广播。
  关于如何使用RemoteViews应用到通知栏和桌面小部件,读者可以参看博客:RemoteViews在桌面小部件和通知栏的使用

Android进阶知识(十六):理解RemoteViews_第1张图片

  通知栏和桌面小部件的开发过程中会用到RemoteViews,它们在更新界面时,由于二者的界面运行在系统的SystemServer进程中,为了跨进程更新界面,RemoteViews提供了一些了set方法

二、RemoteViews支持的View与提供的set方法

  RemoteViews的作用是在其他进程中显示并更新View界面RemoteViews目前并不能支持所有的View类型,其支持的所有类型如下表所示。

Layout View
FrameLayout、LinearLayout、RelativeLayout、GridLayout AnalogClock、Button、Chronometer、ImageButton、ImageView、ProgressBar、TextView、ViewFlipper、ListView、GridView、StackView、AdapterViewFlipper、ViewStub

  RemoteViews没有提供findViewById方法,因此无法直接访问里面的View元素,而必须通过RemoteViews所提供的一系列set方法来完成,这是因为RemoteViews在远程进程中显示。部分set方法如下表所示。

方法名 作用
setTextViewText(int viewId, CharSequence text) 设置TextView的文本
setTextViewTextSize(int viewId, int units, float size) 设置TextView的字体大小
setTextColor(int viewId, int color) 设置TextView的字体颜色
setImageViewResource(int viewId, int srcId) 设置ImageView的图片资源
setImageViewBitmap(int viewId, Bitmap bitmap) 设置ImageView的图片
setInt(int viewId, String methodName, int value) 反射调用View对象的参数类型为int的方法
setLong(int viewId, String methodName, long value) 反射调用View对象的参数类型为long的方法
setBoolean(int viewId, String methodName, boolean value) 反射调用View对象的参数类型为boolean的方法
setOnClickPendingIntent(int viewId, PendingIntent pendingIntent) 为View添加单击事件,事件类型只能为PendingIntent

  RemoteViews的大部分set方法都是通过反射来完成的

三、RemoteViews的内部机制

  通知栏和桌面小部件分别由NotificationManager和AppWidgetManager管理,而这两者通过Binder分别和SystemServer进程中的NotificationManagerServer以及AppWidgetServer进行通信。
  由此可见,通知栏和桌面小部件的布局文件实际上是在NotificationManagerServer以及AppWidgetServer中被加载的,而它们运行在系统的SystemServer中,这就与原进程构成了跨进程通信的场景
Android进阶知识(十六):理解RemoteViews_第2张图片

  RemoteViews的内部机制如图所示。
Android进阶知识(十六):理解RemoteViews_第3张图片

  RemoteViews内部机制的运行步骤为:

  1. RemoteViews通过Binder传递到SystemServer进程

  由于RemoteViews实现了Parcelable接口,因此可以跨进程传输,系统会根据RemoteViews中的包名等信息去得到该应用的资源。

  1. 通过LayoutInflater去加载RemoteViews中的布局文件

  2. 系统对View执行一系列界面更新任务

  这些任务是通过set方法提交的。set方法对View所做的更新并不是立即执行的,在RemoteViews内部会记录所有的更新操作,具体的执行时机要等到RemoteViews被加载以后才能执行
  当需要更新RemoteViews时,需要调用一系列set方法并通过NotificationManager和AppWidgetManager来提交更新任务,具体的更新操作也是在SystemServer进程中完成的。
Android进阶知识(十六):理解RemoteViews_第4张图片

  从理论上来说,系统完全可以通过Binder去支持所有的View和View操作。那为啥不用这种方式呢?
Android进阶知识(十六):理解RemoteViews_第5张图片

  这种方式,由于View的方法太多,代价太大,而且大量的IPC操作会影响效率。因此Android系统提供了Action的概念,Action同样实现了Parcelable接口,封装了具体的操作,然后传输到远程SystemServer进程中
Android进阶知识(十六):理解RemoteViews_第6张图片

四、RemoteViews的意义

RemoteView主要是提供了进程间View更新的一种高效快速的解决方案,主要应用在Notification 和 AppWidgetProvider中。

参考资料:《Android开发艺术探索》

你可能感兴趣的:(Android进阶,理解RemoteViews,RemoteViews内部机制)