Android开发艺术探索》读书笔记 (5) 第5章 理解RemoteViews
第5章 理解RemoteViews
5.1 RemoteViews的应用
(1)RemoteViews表示的是一个view结构,它可以在其他进程中显示。由于它在其他进程中显示,为了能够更新它的界面,RemoteViews提供了一组基础的操作用于跨进程更新它的界面。
(2)RemoteViews主要用于通知栏通知和桌面小部件的开发,通知栏通知是通过NotificationManager的notify方法来实现的;桌面小部件是通过AppWidgetProvider来实现的,它本质上是一个广播(BroadcastReceiver)。这两者的界面都是运行在SystemServer进程中。
(3)RemoteViews在Notification中的应用示例
Notification notification = new Notification(); |
(4)RemoteViews在桌面小部件中的应用
1.定义小部件界面;
2.定义小部件配置信息:其中updatePeriodMillis定义小工具的自动更新周期,单位为ms。
<?xml version="1.0" encoding="utf-8"?> |
3.定义小部件的实现类:书中的示例实现了一个显示一张图片的小部件,每次点击小部件的时候图片就会旋转一周;
public class MyAppWidgetProvider extends AppWidgetProvider {
public static final String TAG = "MyAppWidgetProvider";
|
4.在AndroidManifest.xml文件中声明小部件
下面的示例中包含了两个action,第一个action用于识别小部件的单击行为,而第二个action是作为小部件必须存在的actionandroid.appwidget.action.APPWIDGET_UPDATE,如果不加那么就无法显示小部件。
<receiver android:name=".MyAppWidgetProvider" > |
(5)AppWidgetProvider会自动根据广播的action通过onReceive方法来自动分发广播,也就是调用下面不同的方法:onEnable:当小部件第一次添加到桌面时调用,小部件可以添加多次但是只在第一次添加的时候调用;onUpdate:小部件被添加时或者每次小部件更新时都会调用一次该方法,每个周期小部件都会自动更新一次;onDeleted:每删除一次小部件就调用一次;onDisabled:当最后一个该类型的小部件被删除时调用该方法;onReceive:这是广播内置的方法,用于分发具体的事件给其他方法,所以该方法一般要调用super.onReceive(context, intent); 如果自定义了其他action的广播,就可以在调用了父类方法之后进行判断,如上面代码所示。
(6)PendingIntent表示一种处于Pending状态的Intent,pending表示的是即将发生的意思,它是在将来的某个不确定的时刻放生,而Intent是立刻发生。
(7)PendingIntent支持三种待定意图:启动Activity(getActivity),启动Service(getService),发送广播(getBroadcast)。PendingIntent.getActivity(Context context, in requestCode, Intent intent, int flags)
获得一个PendingIntent,当待定意图发生时,效果相当于Context.startActivity(intent)。
第二个参数requestCode是PendingIntent发送方的请求码,多数情况下设为0即可,另外requestCode会影响到flags的效果。
PendingIntent的匹配规则:如果两个PendingIntent内部的Intent相同,并且requestCode也相同,那么这两个PendingIntent就是相同的。
Intent的匹配规则:如果两个Intent的ComponentName和intent-filter都相同,那么这两个Intent就是相同的,Extras不参与Intent的匹配过程。
第四个参数flags常见的类型有:FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT、FLAG_UPDATE_CURRENT。FLAG_ONE_SHOT:当前描述的PendingIntent只能被调用一次,然后它就会被自动cancel。如果后续还有相同的PendingIntent,那么它们的send方法就会调用失败。对于通知栏消息来说,如果采用这个flag,那么同类的通知只能使用一次,后续的通知单击后将无法打开。FLAG_NO_CREATE:当前描述的PendingIntent不会主动创建,如果当前PendingIntent之前不存在,那么getActivity、getService和getBroadcast方法会直接返回null,即获取PendingIntent失败。这个标志位使用很少。FLAG_CANCEL_CURRENT:当前描述的PendingIntent如果已经存在,那么它们都会被cancel,然后系统会创建一个新的PendingIntent。对于通知栏消息来说,那些被cancel的通知单击后将无法打开。FLAG_UPDATE_CURRENT:当前描述的PendingIntent如果已经存在,那么它们都会被更新,即它们的Intent中的Extras会被替换成最新的。
(8)分析NotificationManager.nofify(id, notification) [未测试,看着有点晕]
1.如果参数id是常量,那么多次调用notify只能弹出一个通知,后续的通知会把前面的通知完全替代掉;
2.如果参数id每次都不同,那么当PendingIntent不匹配的时候,不管采用何种标志位,这些通知之间不会相互干扰;
3.如果参数id每次都不同,且PendingIntent匹配的时候,那就要看标志位:
如果标志位是FLAG_ONE_SHOT,那么后续的通知中的PendingIntent会和第一条通知保持完全一致,包括其中的Extras,单击任何一条通知后,剩下的通知均无法再打开,当所有的通知都被清除后,会再次重复这个过程;
如果标志位是FLAG_CANCEL_CURRENT,那么只有最新的通知可以打开,之前弹出的所有通知都无法打开;
如果标志位是FLAG_UPDATE_CURRENT,那么之前弹出的通知中的PendingIntent会被更新,最终它们和最新的一条通知保持完全一致,包括其中的Extras,并且这些通知都是可以打开的。
5.2 RemoteViews的内部机制
(1)RemoteViews的构造方法 public RemoteViews(String packageName, int layoutId),第一个参数是当前应用的包名,第二个参数是待加载的布局文件。
(2)RemoteViews只支持部分布局和View组件,下面列举的组件的子类是不支持的
布局:FrameLayout、LinearLayout、RelativeLayout、GridLayout
组件:Button、ImageButton、ImageView、TextView、ListView、GridView、ViewStub等
(3)RemoteViews提供了一系列的set方法完成view的设置,这是通过反射完成的调用的。
例如方法setInt(int viewId, String methodName, int value)就是反射调用view对象的名称为methodName的方法,传入参数value,同样的还有setBoolean、setLong等。
方法setOnClickPendingIntent(int viewId, PendingIntent pi)用来为view添加单击事件,事件类型只能为PendingIntent。
(4)通知和小部件分别由NotificationManager和AppWidgetManager管理,而它们通过Binder分别和SystemServer进程中的NotificationManagerService和AppWidgetManagerService进行通信。所以,布局文件实际上是两个Service加载的,运行在SystemServer进程中。
(5)RemoteViews实现了Parcelable接口,它会通过Binder传递到SystemServer进程,系统会根据RemoteViews中的包名信息获取到应用中的资源,从而完成布局文件的加载。
(6)系统将view操作封装成Action对象,Action同样实现了Parcelable接口,通过Binder传递到SystemServer进程。远程进程通过RemoteViews的apply方法来进行view的更新操作,RemoteViews的apply方法内部则会去遍历所有的action对象并调用它们的apply方法来进行view的更新操作。
这样做的好处是不需要定义大量的Binder接口,其次批量执行RemoteViews中的更新操作提高了程序性能。
(7)RemoteViews的apply和reapply方法的区别:apply方法会加载布局并更新界面,而reapply方法则只会更新界面。
(8)setOnClickPendingIntent、setPendingIntentTemplate和setOnClickFillIntent的区别setOnClickPendingIntent用于给普通的view添加点击事件,但是不能给集合(ListView和StackView)中的view设置点击事件,因为开销太大了。如果需要给ListView和StackView中的item添加点击事件,需要结合setPendingIntentTemplate和setOnClickFillIntent一起使用。[并没有尝试(⊙o⊙)]
5.3 RemoteViews的意义
RemoteViews的最大的意义是实现了跨进程的UI更新,这节作者实现了一个模拟通知栏效果的应用来演示跨进程的UI更新,源码传送门。
OK,本章结束,谢谢阅读。
Android开发艺术探索》读书笔记 (5) 第5章 理解RemoteViews的更多相关文章
- Android开发艺术探索读书笔记——01 Activity的生命周期
http://www.cnblogs.com/csonezp/p/5121142.html 新买了一本书,<Android开发艺术探索>.这本书算是一本进阶书籍,适合有一定安卓开发基础,做 ...
- Android开发艺术探索读书笔记——进程间通信
1. 多进程使用场景 1) 应用某些模块由于特殊需求须要执行在单独进程中. 如消息推送,使消息推送进程与应用进程能单独存活,消息推送进程不会由于应用程序进程crash而受影响. 2) 为加大一个应用可 ...
- android开发艺术探索读书笔记之-------view的事件分发机制
View的点击事件的分发,其实就是对MotionEvent事件的分发过程,即当一个MotionEvent产生后,系统需要把这个事件传递给一个具体的View,而这个过程就是分发过程. 分发过程主要由以下 ...
- Android开发艺术探索学习笔记(三)
第三章 View的事件体系 3.1 View基础知识 3.1.1 什么是view View 是Android中所有控件的基类,是一种界面层的控件的一种抽象,它代表了一个控件. 3.1.2 View的 ...
- Android开发艺术探索学习笔记(十一)
第十一章 Android的线程和线程池 从用途上来说,线程分为子线程和主线程,主线程主要处理和界面相关的事情,而子线程往往用于执行耗时的操作.AsyncTask,IntentService,Hand ...
- Android开发艺术探索学习笔记(十)
第十章 Android的消息机制 面试中经常会被问到的一个问题:handler是如何在子线程和主线程中进行消息的传递的,这个问题通过了解Android的消息机制可以得到一个准确的答案. Androi ...
- Android开发艺术探索学习笔记(六)
第六章 Android的Drawable Drawable的优点:使用简单,比自定义view的成本要低:非图片类型的Drawable占用空间小,有利于减小APK安装包的大小. 6.1Drawable ...
- Android开发艺术探索学习笔记(四)
第四章 View的工作原理 4.1初识ViewRoot和DecorView ViewRoot是连接WindowManager和DecorView的纽带,View的三大流程均是通过ViewRoot来完成 ...
- Android开发艺术探索学习笔记(一)
第一章 Activity的生命周期和启动模式 1.1Activity的生命周期全面解析 1.1.1典型情况下的生命周期分析 (1)在两个Activity进行切换时,当前的Activity的onPaus ...
随机推荐
- rel=nofollow 是什么意思
nofollow是什么意思? nofollow是html标签的一个属性值,Google推荐使用nofollow,告诉机器(爬虫)无需追踪目标页,是指禁止蜘蛛爬行和传递权重,但是如果你是通过sitema ...
- coreseek(sphinx)错误:WARNING: attribute 'id' not found - IGNORING
coreseek(sphinx)错误:WARNING: attribute 'id' not found - IGNORING原因及解决方法 coreseek(sphinx)建立索引时提示错误: WA ...
- IE 6最小最大宽度与高度的写法
最小最大宽度,最小最大高度,这是CSS很常见的一个要求.在现代浏览器中,一个 min-height,min-width 就可以解决问题,但是在IE系列,比如IE6则比较繁琐一点.下面总结一些IE 6下 ...
- 概率质量函数:怀孕周期的PMF
__author__ = 'dell' import surveyimport Pmfimport matplotlib.pyplot as pyplot table = survey.Pregnan ...
- DaoImpl中实现查询分页-使用HibernateCallback来做更加方便
/** * */ package com.wolfgang.dao; import java.sql.SQLException; import java.util.List; import org.h ...
- jQuery.dialog
本篇文章主要是对JQUERY中dialog的用法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助 今天用到了客户端的对话框,把 jQuery UI 中的对话框学习了一下. 准备 jQ ...
- WINDOWS下的SALT-MINION安装流水图
简单的下一步下一步, 没多少说的,可以在安装的时候设置MASTER和MINION的东东.. 不多说,上图:
- 《how to design programs》15章 相互引用的数据定义
由结构体组成的表与结构体中的表. 在用追溯形式建立家家谱树时,我们通常从某个后代除法,依次处理它的父母,组父母等.而构建树时,我们会不断添加谁是谁的孩子,而不是写出谁是谁的父母,从而建立一颗后代家谱树 ...
- [LeetCode#110, 112, 113]Balanced Binary Tree, Path Sum, Path Sum II
Problem 1 [Balanced Binary Tree] Given a binary tree, determine if it is height-balanced. For this p ...
- Blue Jeans(串)
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10083 Accepted: 4262 Description The ...