结构和加载流程
一、系统开机启动时AppWidget的加载过程
第一步:Android系统启动,SystemServer创建AppWidgetService,并调用SystemReady()方法,在SystemReady()方法中做以下三项准备工作:
I、通过PackageManager从Android系统中查找所有己经被安装的AppWidget(包含“Android. AppWidget. Action. APPWIDGET_UPDATE”的Action和meta-data标签),解析AppWidget的配置信息,封闭成对象,保存到List集合。
2、从/data/system/AppWidgets. xml文件读取己经被添加到Launcher的AppWidget信息,封闭成对象,保存到List集合中。
3、注册四个广播接收器:第一、Android系统启动完成;第二、Android配置信息改变:第三、添加删除应用;第四、sdcard的安装与卸载。
第二步:Android系统启动Launcher应用程序。Launcher和Widget有着先天的粘连关系,Widget显示在Launcher中,Widget的事件响应由Launcher来控制。
Launcher应用程序启动会做以下准备工作:
1、从Launcher应用的数据库查找已经被添加到Launcher的AppWidget信息。
2、根据查找到的AppWidgetId值(整型值)创建LauncherAppWidgetHostView布局对象。
3、根据查找到的AppWidgetId值(整型值)从AppWidgetService中获取RemoteViews对象(因为是第一次启动所以RemoteViews对象为空)。
4、将获取到的RemoteViews对象的布局解析并设置到2中创建LauncherAppWidgetHostView布局对象中。
5、将LauncherAppWidgetHostView布局对象添加到Launcher的Workspace中(因为RemoteViews对象为空,所以只在Launcher的WorkSpaee中占了一个位置)。
第三步:Android系统启动完成,发出BOOT一COMPLETED广播,AppWidgetS ervice接收到广播后,会做以下工作:
1、获取已经添加到Launcher的AppWidget列表中提到的,依次向这个Widget发出APP WIDGET_ENABLED和APPWIDGET_UPDATE更新广播,根据配置的更新间隔定时发出更新广播。
2、每个AppWidget接收到广播后都会调用onEnabled()方法和onUpdate ()方法。在onEnabled ()方法中进行一些初始化操作,在onUpdate ()方法中创建RemoteViews布局对象,并通过AppWidgetManager的updateAppWidget( int AppWidgetId,RemoteViews RemoteViews)方法通知AppWidgetService对象用RemoteViews对象更新AppWidgetId所对应的AppWidget .
3. AppWidgetService接收到了AppWidgetId和RemoteViews后,通过App WidgetId查找已经被添加到Launcher的LauncherAppWidgetHostView布局对象,并将RemoteViews中的布局更新到LauncherAppWidgetHostView布局对象中,AppWidget显示在Launcher中。
二、用户添加Widget时App Widget的加载流程
第一步:用户长按Launcher弹出添快捷组件的Dialog,选择添加AppWidget,这时会打开一个Activity (AppWidgetPickActivity)显示系统中全部AppWidget,单击某一个AppWidget后会做以下操作:
1.通过AppWidgetService获取一个最新的AppWidgetld值。
2·根据获取的AppWidgetId值,向单击的AppWidget组件发出APPWIDGET_ENABLED和APPWIDGET_UPDATE更新广播,并向//data/system/AppWidgets.xmI中添加此AppWidget的基本信息。
第二步:启动AppWidgetPickActivity (1中提到)时使用的是start,ActivityForResult ()方法,所以在向所单击的AppWidget组件发出APPWIDGETENABLED和APPWIDGETUPDATE更新广播后会执行。nActivityResult)方法,做以下准备工作:
1、将需要被添加到Launcher的AppWidget基本信息保存到数据库中。
2、根据查找到的AppWidgetId(整型值)创建LauncherAppWidgetHostView布局对象。
3、根据查找到的AppWidgetld值(整型值)从AppWidgetSerrvice中获取RemoteViews对象(因为是第一次启动所以RemoteViews对象为空)。
4、将获取到的RemoteViews对象的布局解析并设置到第2步中创建的LauncherAppWidgetHostView布局对象中。
5、将LauncherAppWidgetHostView添加到Launcher的Workspace中(因为RemoteViews对象为空,所以只在Launcher的Workspace中占了一个位置)。
第三步:在第一步中已经向需要添加到Launcher中的AppWidget发出了更新
1、每个AppWidget接收到广播后都会调用onEnabled()方法和onUpdate ()方消息(注意:第一步和第二步是异步执行的),继续做以下事情:
法,在onEnabled()方法中进行一些初始化操作,在onUpdate()方法中创建RemoteViews布局对象并通过AppWidgetManager的updateAppWidget (int AppWidgetId,RemoteViews RemoteViews)方法通知AppWidgetService对象用RemoteViews对象,更新AppWidgetId所对应的AppWidget.
2, AppWidgetService接收到了AppWidgetId和RemoteViews后,通过AppWidgetld查找已经被添加到Launcher的LauncherAppWidgetHostView布局对象,并将RemoteViews中的布局更新到LauncherAppWidgetHostView布局对象中,AppWidget显示在Launcher中。
APPWidget与APP的通信
当Widget被拖到桌面上时,桌面会指定一个保留的空间来显示应用提供的自定义内容。用户可以通过这个Widget来和应用交互,例如music应用程序中的暂停或切换歌曲。如果应用有一个后台服务,用户则可以按照自己的Schedule更新Widget,或者使用AppWidget Framework提供一个自动的更新机制。每个Widget就是一个BroadcastReceiver,它们用XML metadata来描述Widget的细节。AppWidget Framework通过Broadcast Intents和Widget通信,Widget的更新使用RemoteViews来发送。
AppWidget实际上是桌面上一个显示信息的模块,通过单击AppWidget跳转到程序入口类。一个程序既可以通过AppWidget启动,也可以通过App启动。简言之,AppWidget由一个AppWidgetProvider和一个UI界面显示组成,界面上的信息可以通过程序控制而改变。
App Widget运行的进程和用户创建的应用不在一个进程中,所以不能像平常用控件那样来获得控件的实例,而RemoteViews则在这过程起到了很大的作用,通过它用户能够获取不在同一进程中的对象,这也就为AppWidget的处理事件提供了帮助。