ImageVerifierCode 换一换
格式:DOCX , 页数:28 ,大小:484.25KB ,
资源ID:23694586      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/23694586.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(RemoteViews原理分析及应用.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

RemoteViews原理分析及应用.docx

1、RemoteViews原理分析及应用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 opera

2、tions for modifying * 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 RemoteV

4、iews(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 Th

5、e id 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. *

6、* param application 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

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

8、onInfo mApplication;/* * 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可以理解为对远程视图操作的一个封装,下

9、文会详细解释。RemoteView注解在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 Pro

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

12、ayout、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. * * param clazz

14、 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 clazz)返回true,否则返回

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

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

17、bject and applies * all of the actions. * * Caller beware: this may throw * * param context Default context to use * param parent Parent that the resulting view hierarchy will be attached to. This method * does not attach the hierarchy. The caller should do so when appropriate. * return The inflated

18、 view hierarchy */public View apply(Context context, ViewGroup parent) return apply(context, parent, null);接下来会调用:public View apply(Context context, ViewGroup parent, OnClickHandler handler) RemoteViews rvToApply = getRemoteViewsToApply(context); View result = inflateView(context, rvToApply, parent)

19、; loadTransitionOverride(context, handler); rvToApply.performApply(result, parent, handler); return result;先重点关注下面这一行代码:View result = inflateView(context, rvToApply, parent);其内部实现就是常见的布局加载方式了:private View inflateView(Context context, RemoteViews rv, ViewGroup parent) / RemoteViews may be built by an

20、 application installed in another / user. So build a context that loads resources from that user but / still returns the current users userId so settings like data / time formats / are loaded without requiring cross user persmissions. final Context contextForResources = getContextForResources(contex

21、t); Context inflationContext = new ContextWrapper(context) Override public Resources getResources() return contextForResources.getResources(); Override public Resources.Theme getTheme() return contextForResources.getTheme(); Override public String getPackageName() return contextForResources.getPacka

22、geName(); ; LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); / Clone inflater so we load resources from correct context and / we dont add a filter to the static version returned by getSystemService. inflater = inflater.cloneInContext(inflationCont

23、ext); inflater.setFilter(this); return inflater.inflate(rv.getLayoutId(), parent, false);主要关注最后几行代码即可,把握主要流程,一些细节可以暂时忽略。RemoteViews的apply方法中还有这样一行代码:rvToApply.performApply(result, parent, handler);接下来会调用:private void performApply(View v, ViewGroup parent, OnClickHandler handler) if (mActions != null

24、) handler = handler = null ? DEFAULT_ON_CLICK_HANDLER : handler; final int count = mActions.size(); for (int i = 0; i count; i+) Action a = mActions.get(i); a.apply(v, parent, handler); 即遍历RemoteViews中存储的Action,然后执行Action的apply方法。远程View是如何操作的上一小节提到了Action对象,那么Action又是什么呢?由于RemoteViews运行在远端进程中,因此无法通过

25、findViewById的方法来获取View。为了操作远程视图,于是就将对视图的操作封装成一个Action对象,Action是一个实现了Parcelable接口的抽象类,因此可以跨进程传输。先来看下Action的定义:/* * Base class for all actions that can be performed on an * inflated view. * * SUBCLASSES MUST BE IMMUTABLE SO CLONE WORKS! */private abstract static class Action implements Parcelable publ

26、ic abstract void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException; public static final int MERGE_REPLACE = 0; public static final int MERGE_APPEND = 1; public static final int MERGE_IGNORE = 2; public int describeContents() return 0; /* * Overridden by each class

27、 to report on its own memory usage */ public void updateMemoryUsageEstimate(MemoryUsageCounter counter) / We currently only calculate Bitmap memory usage, so by default, / dont do anything here public void setBitmapCache(BitmapCache bitmapCache) / Do nothing public int mergeBehavior() return MERGE_R

28、EPLACE; public abstract String getActionName(); public String getUniqueKey() return (getActionName() + viewId); /* * This is called on the background thread. It should perform any non-ui computations * and return the final on which will run on the UI thread. * Override this if some of the tasks can

29、be performed async. */ public Action initActionAsync(ViewTree root, ViewGroup rootParent, OnClickHandler handler) return this; int viewId;从说明来看,Action就是对远程视图操作的一个封装,它提供了一个抽象方法:public abstract void apply(View root, ViewGroup rootParent, OnClickHandler handler) throws ActionException;该抽象方法需要子类做具体实现。Ac

30、tion有很多子类,几乎每个子类都用来辅助一种View操作,下面简单罗列两个:/* * Helper action to set compound drawables on a TextView. Supports relative * (s/t/e/b) or cardinal (l/t/r/b) arrangement. */private class TextViewDrawableAction extends Action /* * Helper action to set text size on a TextView in any supported units. */private class TextViewSizeAction extends Action 这里不再一一列举,有兴趣的可以参考源码。了解了Action的概念之后,我们以为远程的TextView设置文本为例,来具体看一下其工作流程。平时我们给TextView设置文本只需要调用其setText方法即可,但RemoteViews无法这样使用,RemoteViews提供了一系列关于View操作的set方法,这里会用到如下方法:/*

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1