RemoteViews简介

RemoteViews,根据字面意思应该是一种远程的View,其实RemoteView表示的是一个View结构,它可以在其他进程中显示,由于它在其他进程中显示,为了能够更新它的界面,RemoteViews提供了一组基础的操作用于跨进程更新它的界面。

                          RemoteViews的作用

通过上面的简介,我们也大致了解RemoteViews主要用于实现跨进程更新界面,在实际开发中,RemoteViews主要用于通知栏和桌面小部件的开发。接下来,我们就以一些简单的案例来走进RemoteViews。

                        RemoteViews的简单实用

首先,我们看一下RemoteView在通知栏上的应用。

这里使用Notification简单实现一个通知栏弹窗,关于Notification的使用不是本文的重点,这里便不再详述,读者感兴趣可自行了解。
接下来我们尝试自定义通知栏,我们需要提供提供一个布局文件,然后使用RemoteViews加载此文件,就可以达到实现自定义通知的效果。

这里R.layout.remote布局文件中简单放置了一个imageview以及textview,需要注意的是,这里不可以直接访问布局文件中的view,需要通过remoteViews提供的方法来更新view中的内容。

接下来,我们再来了解一下RemoteViews在桌面小部件上的应用。
再实现桌面小部件之前,我们需要先了解下AppWidgetProvider,它是Android中提供的用于实现桌面小部件的类,其实本质就是一个广播。接下来我们简单地使用RemoteViews实现桌面小部件的开发。

1. 定义小部件界面

新建XML文件,然后自定义里面的布局,我这里命名为widget.xml,里面简单放置了一个ImageView。

2. 定义小部件的配置信息

在res/xml下新建app_provider_info.xml,添加内容如下:

其中,initialLayout加载的就是小部件界面布局,minHeight与minWidth定义小部件的最小尺寸,updatePeriodMillis为小部件自动更新的周期,单位为毫秒。

3. 定义小部件的实现类

这个类需要继承AppWidgetProvider,上面已经谈及AppWidgetProvider本质就是一个广播,所以实现和广播相差不多。

public class MyAppWidgetProvider extends AppWidgetProvider {public static final String TAG = "TAG";public static final String CLICK_ACTION = "app_widget_provider";@Overridepublic void onReceive(final Context context, final Intent intent) {super.onReceive(context, intent);Log.d(TAG, "action:" + intent.getAction());//当收到的action为我们自定义的action时,做一个动画效果的处理if (intent.getAction().equals(CLICK_ACTION)) {new Thread(new Runnable() {@Overridepublic void run() {Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_launcher);AppWidgetManager manager = AppWidgetManager.getInstance(context);for (int i = 0; i < 37; i++) {float degree = (i * 10) % 360;RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget);remoteViews.setImageViewBitmap(R.id.iv_widget,rotateBitmap(context,bitmap,degree));Intent intentClick=new Intent();intentClick.setAction(CLICK_ACTION);PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,intentClick,0);remoteViews.setOnClickPendingIntent(R.id.iv_widget,pendingIntent);manager.updateAppWidget(new ComponentName(context,MyAppWidgetProvider.class),remoteViews);SystemClock.sleep(30);}}}).start();}}//每次桌面小部件更新时都会调用一次@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {super.onUpdate(context, appWidgetManager, appWidgetIds);Log.d(TAG,"app widget provider update...");int count=appWidgetIds.length;Log.d(TAG,"count="+count);for (int i = 0; i < count; i++) {int appWidgetId=appWidgetIds[i];onWidgetUpdate(context,appWidgetManager,appWidgetId);}}/*** 桌面小部件更新操作* @param context* @param manager* @param appWidgetId*/private void onWidgetUpdate(Context context,AppWidgetManager manager,int appWidgetId){RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.widget);Intent intent=new Intent(CLICK_ACTION);PendingIntent pendingIntent=PendingIntent.getBroadcast(context,0,intent,0);remoteViews.setOnClickPendingIntent(R.id.iv_widget,pendingIntent);manager.updateAppWidget(appWidgetId,remoteViews);}/*** 将Bitmap旋转相对应角度* @param context* @param bitmap 原始bitmap* @param degree 角度* @return*/private Bitmap rotateBitmap(Context context,Bitmap bitmap,float degree){Matrix matrix=new Matrix();matrix.reset();matrix.setRotate(degree);Bitmap temBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);return temBitmap;}

上面代码实现了一个简单的桌面小部件,小部件中显示一张图片,点击它,图片会旋转一周,小部件被添加到桌面后,通过RemoteViews加载布局文件,当小部件被单击后的旋转效果则是通过不断更新RemoteViews来实现的,所以,桌面小部件不管是初始化界面还是后续界面更新,都需要通过RemoteViews来完成。

4. 在AndroidManifest.xml中声明小部件

因为桌面小部件本质上是一个广播组件,因为需要注册。

   <!--注册桌面小部件--><receiver android:name=".MyAppWidgetProvider"><meta-dataandroid:name="android.appwidget.provider"android:resource="@xml/app_provider_info"></meta-data><intent-filter><action android:name="app_widget_provider"></action> //标志点击行为<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action> //作为小部件的标识,必须存在</intent-filter></receiver>

AppWidgetProvider中的常用方法

方法名 解释
onUpdate 每次桌面小部件更新时都调用一次该方法,更新时机由updatePeriodMillis来指定,每个周期小部件都会自动更新一次
onEnable 小部件第一次添加到桌面时调用,可以添加多次但只在第一次调用
onDelete 删除一次桌面小部件就调用一次
onDisable 最后一个该类型的桌面小部件被删除时调用
onReceive 广播的内置方法,分发具体事件
                           PeddingIntent概述

peddingIntent表示一种处于pending状态的意图,pending状态表示一种待定、等待、即将发生。就是说接下来有一个Intent将要在某个待定的时刻发生。PendingIntent和Intent的区别在于,PendingIntent是在将来某个时刻发生,而Intent是立刻发生。PendingIntent典型的使用场景是给RemoteViews添加单机事件。由于RemoteViews运行在远程进程中,无法直接调用setOnClickListener方法来设置单击事件,就需要使用pendingIntent,PendingIntent通过send和cancel来发送和取消待定的Intent。

PendingIntent支持的三种待定意图:启动Activity、启动Service以及发送广播。
方法原型|解释
—|—|
getActivity(Context context,int requestCode,Intent intent,int flags)|获取一个pendingIntent意图,意图发生时,相当于startActivity(Intent)
getService(Context context,int requestCode,Intent intent,int flags)|获取一个pendingIntent意图,意图发生时,相当于startService(Intent)
getBroadcast(Context context,int requestCode,Intent intent,int flags)|获取一个pendingIntent意图,意图发生时,相当于sendBroadcast(Intent)

第二个参数requestCode,requestCode表示PendingIntent方的请求码,多数情况设为0即可。

PendingIntent的匹配规则为:如果两个PendingIntent它们内部的Intent相同并且 requestCode也相同则相同。其中Intent相同指ComponentName和intent-filter都相同。

另外flags常见类型如下。

flags类型 解释
FLAG_ONE_SHOT PendingIntent只被使用一次,然后被自动cancel,后续如果还有相同的PendIntent,那么它们的send方法调用失败
FLAG_CANCEL_CURRENT 当前描述的PendIntent如果已经存在,那么它们会被cancel,然后系统创建一个新的PendingIntent。
FLAG_UPDATE_CURRENT 当前描述的PendIntent如果已经存在,那么它们都会被更新。
                             remoteviews的工作原理

通知栏以及小部件分别由NotificationManager和AppWidgetManager管理,而NotificationManager以及AppWidgetManager通过Binder分别和SystemServer进行中的NotificationManagerService以及AppWidgetService进行通信,因此,通知栏以及桌面小部件中的布局文件是在NotificationManagerService以及AppWidgetService中被加载的,而它们运行在系统的systemServer中,这就和我们的进行构成了跨进程通信的场景。
这里没有使用Binder进行进程通信,由于View的方法太多大量的IPC操作会影响效率,这里提供了Action的概念,Action代表一个View的操作,系统将Action操作封装到Action对象并将这些对象跨进程传输到远程进程中,接着直接Action对象中的Action操作。我们使用RemoteViews时,每调用一个set方法,就会添加一个Action对象,当我们通过NotificationManager和AppWidgetManager提交更新时,这些Action对象就会传输到远程进程中并依次执行。

注意,当我们调用RemoteViews的set方法时,并不会立刻更新它们的界面,必须通过NotificationManager的notify方法以及AppWidgetManager的updateAppWidget方法才会更新他们的界面。

参考文献

Android开发艺术探索第5章 《理解RemoteViews》

RemoteViews的作用和工作原理相关推荐

  1. selenium之作用和工作原理

    selenium之作用和工作原理 selenium的作用和工作原理 利用浏览器原生的API,封装成一套更加面向对象的Selenium WebDriver API,直接操作浏览器页面里的元素,甚至操作浏 ...

  2. 工业以太网交换机的作用和工作原理详解

    工业以太网交换机是基于以太网传输数据的交换机,以太网采用共享总线型传输媒体方式的局域网.工业以太网交换机的结构是每个端口都直接与主机相连,并且一般都工作在全双工方式.交换机能同时连通许多对端口,使每一 ...

  3. mysql中主从复制包括什么意思_Mysql主从复制作用和工作原理

    一.什么是主从复制 主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库,主数据库一般是准实时的业务数据库.在最常用的mysql数据库中,支持单项.异步赋值.在赋值过程中,一个服务器充 ...

  4. 简述网卡的作用和工作原理_发电机调节器的作用及工作原理

    发电机由发动带动,其转速则是由发动机转速所决定.工作时,发动机转速变化范围很大,这势必对发电机输出电压的大小有很大影响,为使发电机电压 在不同的转速下均能保持一定,且能随发电机转速的变化而自动调节,使 ...

  5. 串口服务器的作用和工作原理是什么

    要了解串口服务器的作用以及工作原理,首先我们就要知道什么是串口服务器,简单来说串口服务器就是一种网络通讯接口转换设备,它可以将我们一些常见的RS232.RS485.RS422串口转换成TCP/IP网络 ...

  6. 滑环电刷作用及工作原理相关介绍

    随着滑环电刷的应用领域越来越广泛,需求量越来越大的今天,如果各位还不知道滑环电刷作用就真的是跟不上工业发展了.下面默孚龙的专家们就来给大家科普一下什么是滑环电刷. 滑环电刷 绕线型异步机虽然在起动和调 ...

  7. 光耦的作用及工作原理是什么

    光耦的作用及工作原理是什么 介绍 光耦指的是光耦合器,在数字电路上获得广泛的应用,那么光耦的作用及工作原理是什么呢?这就来了解下吧. 什么是光耦 光耦合器(opticalcoupler equipme ...

  8. TLB的作用及工作原理

    TLB的作用及工作过程 以下内容摘自<步步惊芯--软核处理器内部设计分析>一书 页表一般都很大,并且存放在内存中,所以处理器引入MMU后,读取指令.数据需要访问两次内存:首先通过查询页表得 ...

  9. Cookie和Session的作用和工作原理

    一.Cookie详解 (1)简介 因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现.在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两饮料 ...

最新文章

  1. B. Om Nom and Dark Park
  2. C++11特性:override
  3. java map 查找_Map 查找表操作
  4. android fragment动态添加,Android动态添加Fragment
  5. Node中Exports与module.export的使用与区别
  6. 自动化运维之部署Puppet
  7. hibernate乐观锁_Hibernate Collection乐观锁定
  8. 第三章 JVM内存回收区域+对象存活的判断+引用类型+垃圾回收线程
  9. Maple: 多项式相乘
  10. 拓端tecdat|R语言用相关网络图可视化分析汽车配置和饮酒习惯
  11. vue---EleElement UI 表格导出功能
  12. 数字图像处理技术与人脸识别
  13. 团队展示——我说的都队
  14. 计算机工程学院运动会加油稿50字,校园运动会加油稿50字
  15. 析构之后:万物重生! 小岚Rabbit_Radish(兔仔_萝卜)
  16. 我们到底在恐惧什么?
  17. 腾讯地图发送定位-打开定位功能
  18. 进出队C语言不用链表,C语言面试题总汇简要
  19. easyexcel 列头合并_2020-05-19:EasyExcel自定义合并单元格
  20. vue.runtime.esm.js?2b0e:619 [Vue warn]: Duplicate keys detected: ‘xxx‘. This may cause an update err

热门文章

  1. 赛迪智库:政务数据不愿共享的成因及对策
  2. 2019浙江C语言二级答案,2018年浙江省计算机二级c语言考试真题及答案
  3. 齐鲁云采入驻条件是什么
  4. 网络上的计算机之间又是如何交换信息的。(TCP/IP协议、IPX/SPX协议、NetBEUI协议)
  5. mac/linux如何查询外网ip地址
  6. 【白兔兔】- 用LaTeX排版第八届中国大学生数学竞赛决赛(数学类)试卷
  7. 移动数据和软件更新系统及方法
  8. 微信小商店支持个人开店了,详细开店步骤奉上
  9. linux下查看文件的权限,Linux下查看文件权限、修改文件权限的方法
  10. MIFARE-4.0.2