remoteviews原理分析及应用

上传人:第*** 文档编号:31081661 上传时间:2018-02-04 格式:DOC 页数:21 大小:590KB
返回 下载 相关 举报
remoteviews原理分析及应用_第1页
第1页 / 共21页
remoteviews原理分析及应用_第2页
第2页 / 共21页
remoteviews原理分析及应用_第3页
第3页 / 共21页
remoteviews原理分析及应用_第4页
第4页 / 共21页
remoteviews原理分析及应用_第5页
第5页 / 共21页
点击查看更多>>
资源描述

《remoteviews原理分析及应用》由会员分享,可在线阅读,更多相关《remoteviews原理分析及应用(21页珍藏版)》请在金锄头文库上搜索。

1、RemoteViews 原理分析及应用RemoteViews 基本概念RemoteViews 乍一看名字似乎也是一种 View,实则不然,它并不是 View。来看RemoteViews 的定义及官方说明:/* A class that describes a view hierarchy that can be displayed in* another process. The hierarchy is inflated from a layout resource* file, and this class provides some basic operations for modify

2、ing* the content of the inflated hierarchy.*/public class RemoteViews implements Parcelable, Filter 我们可以得到以下几点结论:RemoteViews 只是一个实现了 Parcelable 和 Filter 接口的类,而并非继承自 View。RemoteViews 用来描述可运行在其他进程中的视图结构,但 RemoteViews 本身不是视图,只是一个描述类。RemoteViews 描述的远程视图需要通过 layout 资源文件定义。RemoteViews 类提供了一系列修改远程视图的方法。现在我

3、们对 RemoteViews 应该有了一个大概的认识,它可以跨进程来显示和更新视图。RemoteViews 主要有两个应用场景:自定义通知栏桌面小部件本文最后会给出 RemoteViews 的应用实例,接下来我们先分析 RemoteViews 的实现原理。RemoteViews 原理分析构造函数RemoteViews 提供了多个构造函数,如:public RemoteViews(String packageName, int layoutId) public RemoteViews(String packageName, int userId, int layoutId) public Rem

4、oteViews(RemoteViews landscape, RemoteViews portrait) public RemoteViews(Parcel parcel) 以一个最常用的构造方法为例:/* Create a new RemoteViews object that will display the views contained* in the specified layout file.* param packageName Name of the package that contains the layout resource* param layoutId The i

5、d of the layout resource*/public RemoteViews(String packageName, int layoutId) this(getApplicationInfo(packageName, UserHandle.myUserId(), layoutId);由注释可知,第一个参数为包名,第二个参数为布局资源文件的 ID,接下来会调用:/* Create a new RemoteViews object that will display the views contained* in the specified layout file.* param a

6、pplication The application whose content is shown by the views.* param layoutId The id of the layout resource.* hide*/protected RemoteViews(ApplicationInfo application, int layoutId) mApplication = application;mLayoutId = layoutId;mBitmapCache = new BitmapCache();/ setup the memory usage statisticsm

7、MemoryUsageCounter = new MemoryUsageCounter();recalculateMemoryUsage();同样也很简单,第一个参数为远程视图展示内容所属的 Application 信息,第二个参数为布局文件 ID。该构造方法主要是初始化 mApplication 与 mLayoutId,其他代码为图片缓存及内存计算的一些逻辑。核心属性字段RemoteView 有如下几个比较重要的属性字段:/* Application that hosts the remote views.* hide*/private ApplicationInfo mApplicatio

8、n;/* The resource ID of the layout file. (Added to the parcel)*/private final int mLayoutId;/* An array of actions to perform on the view tree once it has been* inflated*/private ArrayList mActions;前两个比较好理解,而且上文提到是在构造函数中赋值的。mActions 是用来存储 Action 的一个列表,而 Action 可以理解为对远程视图操作的一个封装,下文会详细解释。RemoteView 注解

9、在 RemoteViews 源码中声明了如下注解:/* This annotation indicates that a subclass of View is alllowed to be used* with the link RemoteViews mechanism.*/Target( ElementType.TYPE )Retention(RetentionPolicy.RUNTIME)public interface RemoteView 从注解类型来看为运行时注解,作用于类或接口,结合注释可知此注解用于 View 的子类,用来标识该 View 是否可以作为远程视图使用。由此我们也

10、可以推断,并非所有 View 都可以作为远程视图,只有声明了 RemoteView 注解的 View 才可以。我们从源码定义来简单验证一下:TextView 的定义RemoteViewpublic class TextView extends View implements ViewTreeObserver.OnPreDrawListener Button 的定义RemoteViewpublic class Button extends TextView ImageView 的定义RemoteViewpublic class ImageView extends View ProgressBar

11、 的定义RemoteViewpublic class ProgressBar extends View LinearLayout 的定义RemoteViewpublic class LinearLayout extends ViewGroup EditText 的定义public class EditText extends TextView 不再一一列举,可见 EditText 虽然是继承自 TextView 的,但它没有使用RemoteView 注解,因此并不能用作远程视图。RemoteViews 所支持的 View 类型如下:LinearLayout、RelativeLayout、Fra

12、meLayout 、GridLayout、AbsoluteLayout(已弃用)TextView、Button、ImageView、ImageButton、Chronometer、ProgressBar、ListView、GridView、StackView 、ViewFlipper、AdapterViewFlipper、ViewStub、AnalogClock(已弃用)也就是说远程视图只能使用上述所列举的 View,它们的子类及其他 View 都是不支持的,如果使用了不支持的 View,则会报异常。实现 Parcelable 和 Filter 接口的意义Parcelable 比较容易理解,就

13、是支持序列化以便于跨进程操作。那么 Filter 的作用是什么呢?Filter 接口的定义如下:/* Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed* to be inflated.* */public interface Filter /* * Hook to allow clients of the LayoutInflater to restrict the set of Views * that are allowed to be inflated.* *

14、 param clazz The class object for the View that is about to be inflated* * return True if this class is allowed to be inflated, or false otherwise*/SuppressWarnings(unchecked)boolean onLoadClass(Class clazz);从注释中不难看出 Filter 是用来限制和过滤 View 用的,上文提到并非所有的 View 都能用作远程视图,如果为上述列举的 View,则 onLoadClass(Class c

15、lazz)返回 true,否则返回false。在 RemoteViews 中实现了 Filter 接口的方法:public boolean onLoadClass(Class clazz) return clazz.isAnnotationPresent(RemoteView.class);可以看到就是根据RemoteView 注解来判断是否可以使用该 View 作为远程视图。RemoteViews 实现原理跨进程是哪两个进程很显然我们的应用自身是一个进程,那么另一个进程是什么呢?在 RemoteViews 的应用场景中,如自定义通知栏和桌面小部件,它们都运行在系统进程中,即 SystemSe

16、rver 进程。如此一来,远程视图运行在 SystemServer 进程中,我们在自己的应用进程中跨进程来操作远程视图。前文说到 RemoteViews 实现了 Parcelable 接口,那么 RemoteViews 便可以从应用进程传输到系统进程了。远程 View 是如何加载的通常情况下,我们使用 LayoutInflater 加载布局只需要知道布局 ID 即可。还记得前文讲RemoteViews 的构造函数时,有两个重要的字段:mApplicationmLayoutId在系统进程中加载远程视图正是利用了上述两个字段。在 RemoteViews 的源码中加载布局的逻辑如下:/* * Inflates the view hierarchy represented by this object and applies* all of the actions.*

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号