离开android开发一年半时间,终于又回到久违的android开发,与2011比,android系统更是搞得风生水起,市面上充斥着各种android系统的产品,从手机到电视,从医疗设备到汽车电子,魔多之眼在召唤,我又回来了,离开那与世隔绝小镇(无外网访问的一家it公司),来到中土世界,终于又可以在csdn写博客了。

废话不多说,进入正题,最近两周查一个桌面插件(appwidget)问题,搞两周下来感觉对桌面插件的认识有了一个深入,全面的认识,有必要把它给总结一下,就从一个简单的textview的桌面插件为例开始讲起吧,这个例很简单,android应用开发解密和android sdk中带的demo都有,就是不断更新桌面插件textview的文本,很容易获取这样一个例子,你可以先下一个安装下,对桌面插件有一个直观的认识,本文不是告诉你怎么写一个桌面插件应用,而是阐述其内部实现机制。

首先,我想我们得了解一个问题,那就是桌面插件是什么?先看AndroidManifest.xml中对一个桌面插件的定义

       <receiver android:name=".ExampleAppWidgetProvider"><meta-data android:name="android.appwidget.provider"android:resource="@xml/appwidget_provider" /><intent-filter><action android:name="android.appwidget.action.APPWIDGET_UPDATE" /><action android:name="android.appwidget.action.APPWIDGET_DELETED" /><action android:name="android.appwidget.action.APPWIDGET_DISABLED" /><action android:name="android.appwidget.action.APPWIDGET_ENABLED" /><action android:name="android.appwidget.action.APPWIDGET_ENABLED" /></intent-filter></receiver>

ExampleAppWidgetProvider是一个桌面插件provider类,它继承AppWidgetProvider,从AndroidManifest.xml中对一个桌面插件的定义中我们可以看出ExampleAppWidgetProvider实质上是一个BroadcastReceiver(广播接受器),从下面的类继承关系图我们也可以看出这一点:

但肯定它是有区别与一个普通的广播接收器的,试想,当我们添加桌面插件到桌面时有一个桌面插件选择列表,列表是有包管理器(packagemanager)加载出来的,packagemanager必须要知道它是桌面插件而非只是一个广播接收器,否则它是没有办法得出这个列表的,而决定一个BroadcastReceiver是否是一个AppWidgetProvider的玄机就是receiver中的meta-data定义,因为AppWidgetService服务启动就会加载所有桌面插件,所以我们就可以从AppWidgetService服务启动去剖析它

AppWidgetService->systemReady->loadAppWidgetList:

    /**通过PackageManager加载所有系统插件应用*/void loadAppWidgetList() {PackageManager pm = mPackageManager;Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);//查询所有的broadcastReceiversList<ResolveInfo> broadcastReceivers = pm.queryBroadcastReceivers(intent,PackageManager.GET_META_DATA);final int N = broadcastReceivers == null ? 0 : broadcastReceivers.size();//遍历所有的broadcastReceivers,添加providerfor (int i=0; i<N; i++) {ResolveInfo ri = broadcastReceivers.get(i);//添加一个Provider若这个broadcastReceivers包含//name="android.appwidget.provider"的meta-dataaddProviderLocked(ri);}}

关键函数是这个loadAppWidgetList->addProviderLocked->parseProviderInfoXml:

    private Provider parseProviderInfoXml(ComponentName component, ResolveInfo ri) {Provider p = null;ActivityInfo activityInfo = ri.activityInfo;XmlResourceParser parser = null;try {//获取一个xml文件解析器,对应的xml解析文件是META_DATA_APPWIDGET_PROVIDER//这个meta_data指定的xml文件parser = activityInfo.loadXmlMetaData(mPackageManager,AppWidgetManager.META_DATA_APPWIDGET_PROVIDER);if (parser == null) {Slog.w(TAG, "No " + AppWidgetManager.META_DATA_APPWIDGET_PROVIDER + " meta-data for "+ "AppWidget provider '" + component + '\'');return null;}

上面这一段代码清楚地说明了我前面提到的问题 :决定一个BroadcastReceiver是否是一个AppWidgetProvider的玄机就是receiver中的meta-data定义,你可以看一下AppWidgetManager.META_DATA_APPWIDGET_PROVIDER="android.appwidget.provider",它是一个meta-data name通过它获取到一个xml文件资源,得到一个xml文件解析器,若没有定义这个meta-data显然parser==null,那就不能生成返回一Provider对象,这就是为什么普通BroadcastReceiver不会当作桌面插件来处理的原因

继续往下,AppWidgetService会根据meta-data指定的xml文件生成一个Provider对象,先看一下这个xml文件的定义:

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"android:minWidth="100dp"android:minHeight="50dp"android:updatePeriodMillis="50"android:initialLayout="@layout/appwidget_provider"android:configure="com.yarin.android.Examples_09_07.Activity01">
</appwidget-provider>

这个xml文件定义了一个桌面插件的配置信息,我这里对一些基本属性作了一个总结:

--android:minWidth:指定桌面组件的最小宽度,与AppWidget -ProviderInfo. minHeight成员对应

--android:minHeight: 指定桌面组件的最小高度,与AppWidget -ProviderInfo. minWidth成员对应

--android:updatePeriodMillis:指定桌面组件的更新周期,与AppWidget –ProviderInfo. updatePeriodMillis成员对应,这个注意AppWidgetService中作了一个限制,更新周期最少30分钟

--android:initialLayout:指定桌面组件初始化布局文件,与AppWidget –ProviderInfo. initialLayout成员对应,后面可为RemoteViews对象重新设置布局文件

--android:configure:指定桌面组件创建时候的一个初始配置activity,与AppWidgetProviderInfo. configured对应,可选。

遍历系统所有的BroadcastReceiver后,会在AppWidgetService中生成一个桌面插件应用列表mInstalledProviders,我这里把这个数据结构给描述一下,以便有一个直观认识:

前面xml中桌面插件配置信息都放在了AppWidgetProviderInfo中,当需要获取系统所有安装的桌面插件信息时,就可以调用getInstalledProviders获取,实质上就是获取mInstalledProviders列表。

讲到这里我们再会过头前面我提出的问题,什么是桌面插件,是不是已经解答了?不然,我说到这里其实只是讲了桌面插件应用,说到桌面插件应用与桌面插件的关系你可以理解为类与对象的关系,桌面插件应用是静态的类型,桌面插件是动态生成的实例,为了便于理解我后面统一称为桌面插件实例,那我们继续解答什么是桌面插件这一问题。既然是桌面插件,那我们就从桌面入手,分析桌面插件是如何生成和添加的。

欲知后事如何,请听下回分解。

AppWidget实现机制分析--什么是桌面插件相关推荐

  1. AppWidget实现机制分析--launcher添加和删除appwidget深入分析

    通过前面的<什么是桌面插件>的讲解,估计你对桌面插件应用有了一定的了解,接着那这篇文章,我们继续讲解在一个桌面上如何创建一个桌面插件实例,以及它是如何显示在我们的桌面上的,如何被删除的,这 ...

  2. Apache Nutch 1.3 学习笔记十(插件机制分析)

    1. 一些对象说明 PluginRepository:这是一个用于存储所有插件描述对象(PluginDescriptor),插件扩展点(ExtensionPoint)和被激活的插件. PluginDe ...

  3. 天气预报--桌面插件功能

    我的桌面插件大概分了两块,一块为一个小的桌面时钟,根据系统时间变化来设定时间.第二个是几个Textview和一个imageView来显示当前城市的天气,温度,还有一个小的天气图标. 小插件的实现要自己 ...

  4. JDK源码分析——Java的SPI机制分析与实战

    重点提示:在我博客中的所有的源码分析的实例,我都将会放到github上,感兴趣的朋友可以下载下来调试运行,我相信还是可以有所收获的.我的目的是让所有读到我博客的朋友都可以了解到有价值的东西,学习到ja ...

  5. android 桌面插件 语录,一句话心情语录app

    一句话心情语录app是一个心情阅读软件,这里有着一句句优美的语言,用一段段真挚的语言来温暖你我的身心,一句真挚的话语,洗涤心灵的尘埃,带给你温暖的心语.一句充满知识.智慧和感情的话语,柔软.温暖,充满 ...

  6. Linux:设置/修改linux主机名+hosts映射+主机名解析机制分析+DNS域名劫持

    设置/修改主机名 查看主机名hostname,修改主机名(在vim编译器里修改),重启命令(reboot),操作如下: 结果如下: 设置hosts映射: 操作意义:ip地址很长,不好记忆,直接记忆主机 ...

  7. Android开发桌面插件

    前提:公司应用需要开发插件,奈何我实在没有块的开发经验,查阅了一些资料,花了几天时间,完成了插件的开发. 开发桌面插件需要了解AppWidgetProvider,RemoteViewsService, ...

  8. Google Test(GTest)使用方法和源码解析——结果统计机制分析

    在分析源码之前,我们先看一个例子.以<Google Test(GTest)使用方法和源码解析--概况 >一文中最后一个实例代码为基准,修改最后一个"局部测试"结果为错误 ...

  9. Linux内核抢占实现机制分析【转】

    Linux内核抢占实现机制分析 转自:http://blog.chinaunix.net/uid-24227137-id-3050754.html [摘要]本文详解了Linux内核抢占实现机制.首先介 ...

最新文章

  1. C++ 笔记(33)— C/C++ 程序员常见面试试题深入剖析
  2. 实现简单递归c++实现
  3. 在WINCE5.0开始菜单中添加应用程序
  4. Android中的JSONObject和JSONArray的使用
  5. mint-UI引用后样式不对
  6. sqlserver 的一些好用的插件
  7. 有关javabean的说法不正确的是_【以案说法】从业人员劳动保护用品费不能省!否则得不偿失.........
  8. java中大数字表示什么_JAVA中大数字的的处理:BigInteger和BigDecimal
  9. SilverLight:布局(3)StackPanel 对象
  10. 微软总部首席测试专家做客中关村图书大厦“说法”
  11. springBoot集成Activiti6
  12. 2021-03-30 libnice 应用 多线程
  13. 人工智能神经网络概念股,神经网络芯片概念股
  14. 百度竞价新人提升赚钱概率的技巧方法
  15. 软件工程(2019)第四次作业
  16. word中如何删除最后一页且不影响前面一页的格式
  17. java生成word样式变形的解决方案(freemarker生成word的样式不对)
  18. 中国电热水器行业发展现状及趋势分析,头部厂商市场份额进一步上升「图」
  19. CMS:内容(文章)管理系统
  20. 韩国两大火暴美女迪厅拼舞 精彩视频

热门文章

  1. 有关ACM学习的博客链接
  2. 智能传感器产业三年行动指南
  3. 白帽黑客眼中的网络安全 挡黑客财路曾收恐吓信
  4. Problem 69:Totient maximum
  5. Git与GitHub学习笔记(一)如何删除github里面的文件夹?
  6. 震惊!!!CSS垂直居中竟然有这么多方法~
  7. ubuntu安装经常使用记录
  8. OSChina 周一乱弹 —— 最无法理解的程序员行为
  9. ceph 对接openstack mitaka
  10. 实现类似美团的下拉分级式菜单