今天进行一个Android AppWidget的开发,参考 android SDK 文档中关于App Widgets 开发的部分,可以很容易的完
成整个过程的搭建,文档中的 ExampleAppWidgetProvider.java 和 ExampleAppWidgetConfigure.java 中都拿到了一
个很重要的参数,分别是:appWidgetId 和 mAppWidgetId ,可是,对于这个参数是怎么来的,文档中却没有介绍。
这个问题涉及到 android 和 android AppWidget 的启动过程,下面是我使用 Powerpoint 画的一个 android
AppWidget的加载流程:
从这个图中可以很容易的看到这个参数的来源和走向,我在这里做一个简略的解释:
1. Android系统启动,SystemServer创建AppWidgetService,并调用systemReady()方法,在该方法中:
(1)通过 PackageManager 从 AndroidManifest.xml 中查找所有的 AppWidget ,即:找到包含
android.appwidget.action.APPWIDGET_UPDATE 和 meta-data 的标签信息,如:
<receiver android:name="MyWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
</intent-filter>
<meta-data android:resource="@xml/widget_property" android:name="android.appwidget.provider"></meta-data>
</receiver>
解析其中的AppWidget的配置信息,即:android:resource="@xml/widget_property",将其封装成对象
保存到本地数据成员中。
(2)从/data/system/appwidgets.xml文件读取已经被添加到Launcher的AppWidget信息,封闭成对象,所有已
安装到桌面的widget的信息都保存在这个文件里。读出来,保存到本地数据成员里。
(3)注册了四个消息:ACTION_BOOT_COMPLETED(系统启动到桌面就会发送此消息),
ACTION_PACKAGE_ADDED(有新APK包安装到系统),ACTION_PACKAGE_REMOVED(有APK包被删除)
和 sdcard的安装与缷载。当系统启动到桌面后,AppWidgetService接收到了ACTION_BOOT_COMPLETED消
息,它会去检查本地数据成员,如果有已经安装到桌面的widget,它会上发ACTION_APPWIDGET_ENABLED和
ACTION_APPWIDGET_UPDATE消息。如果有widget设置了updatePeriodMillis的属性,它就会开始计时(这个是
通过AlarmManager来实现的),到时间时,就会再次上发ACTION_APPWIDGET_UPDATE消息。
2. Android 系统启动 Launcher 应用程序,从 Launcher 中查找 AppWidget 信息,取得 appWidgetId ,根据这个
appWidgetId 值,创建 LauncherAppWidgetHostView 布局对象,同时也是根据这个 appWidgetId 值从
AppWidgetService中获取RemoteViews对象 。
3. Android系统启动完成后,会发出 BOOT_COMPLETED 广播,AppWidgetService 会接收到这个广播,然后
AppWidgetService 会做如下处理:
(1)获取已经添加到 Launcher 的 AppWidget 列表,在这里也得到了参数 appWidgetId ,依次向其中的 Widget
发出 APPWIDGET_ENABLED 和 APPWIDGET_UPDATE 更新广播。
(2)每个 AppWidget 都会接收到广播,同时也会得到参数 appWidgetId , 然后每个 AppWidget 都会调用其
onEnabled()方法和onUpdate()方法。
(3)AppWidgetService 接收到了 appWidgetId 和 RemoteViews 后,将 RemoteViews 中的布局更新到
LauncherAppWidgetHostView 布局对象中。