RemoteViews内部机制
首先RemoteViews会通过Binder传递到SystemServer进程,这是因为RemoteViews实现了Parcelable接口,因此它可以跨进程传输,系统会根据RemoteViews中包名信息去得到该应用资源。
然后通过LayoutInflater去加载RemoteViews中布局文件。在SystemServer进程中加载后的布局文件是一个普通的View,只不过相对于我们的进程它是一个RemoteViews而已。
接着系统会对View所做的更新并不是立刻执行的,在RemoteViews内部会记录所有的更新操作,具体的执行时机要等到RemoteViews被加载以后才会执行,这样RemoteViews就可以在SystemServer进程中显示了,这就是我们所看到的通知栏信息或者桌面小部件。
当需要更新RemoteViews时,我们需要调用一系列set方法并通过NotificationManager和AppWidgetManager来提交更新任务,具体的更新操作也是在SystemServer进程中进行的
从理论上来说,系统完全可以通过Binder去支持所有的View和View操作,但是这样做的话代价太大,因为View的方法太多了,另外就是大量的IPC操作会影响效率。
为了解决这个问题,系统并没有通过Binder去直接支持View的跨进程访问,而是提供了一个Action的概念,Action代表一个View操作,Action同样实现了Parcelable接口。
系统首先将View操作封装在具体的操作。在我们的应用中每调用一次set方法,RemoteViews中就会添加对应的Action对象,当我们通过NotificationManager和AppWidgetManager来提交我们的更新时,这些Action对象就会传输到远程进程并在远程进程中一次执行,远程进程通过RemoteViews的apply方法来进行View的更新操作,RemoteViews的apply方法内部则会去遍历所有的Action对象并调用他们的apply方法,具体的View更新操作是由Action对象的apply方法来完成