2012-8-21
Launcher在Android的AppWidget整个体系中扮演AppWidgetHost的角色,本文分析Launcher对于AppWidget的处理,主要包括:选取AppWidgetProvider之后的处理;Launcher初始化过程中加载(包括第一次加载和之后正常的加载)AppWidget信息的处理,等。
由《Android中选取并绑定AppWidget》中知道,Launcher发起选取操作;Settings中的AppWidgetPickActivity获取所有已经安装的AppWidgetProvider,让用户选择,用户选择之后,回到启动它的Activity的onActivityResult()。
先看Launcher中定义的用来处理AppWidget的相关的类:
图一、Launcher中AppWidget的相关类
图二的时序图描述了,从AppWidgetPickActivity返回之后,Launcher如何处理AppWidget的。
图二、Picked之后Launcher对AppWidget的处理
执行过程:
1.onActivityResult()中,从requestCode以及resultCode里知道,选取AppWidget成功,可以从返回的data:Intent中获得appWidgetId;[Seq#1]
2.通过AppWidgetId获得info: AppWidgetProviderInfo;[Seq#5~ #6]
3.创建LauncherAppWidgetInfo的实例,并加入到数据模型LauncherModel中;[Seq#7]
4.通过LauncherAppWidgetHost.createView()创建AppHostView;[Seq#8~ #15]
5.向AppWidgetHostView里设置TAG – LauncherAppWidgetInfo的实例。[Seq#17]
最后,LauncherAppWidgetHostView被加入到当前屏,让相应的显示部分来完成显示。因为此时RemoteViews里可能还没有内容,这里只是用一定的占空在Workspace中先占一定的空间。
当AppWidgetProvider获得更新的广播,并执行onUpdate(),onUpdate()中创建了RemoteViews并通过AppWidgetManager.updateAppWidget()更新到AppWidgetService之后,AppWidgetService会通过注册的IAppWidgetHost的回调,执行AppWidgetHost的更新。
图三、AppWidgetHost被更新
《Android中RemoteViews的实现》中的Section#3讲述了RemoteViews后续的处理。
Launcher在初始化过程中,还会根据配置在第一次创建Database时把AppWidget加载进来;不是第一次创建时,把数据库中的AppWidget的内容Load到数据模型中。
Launcher的数据库操作的相关的类
图四、Launcher的数据库操作LauncherProvider
Launcher第一次创建数据库时,LauncherProvider.DatabaseHelper.onCreate()会被执行,对AppWidget的处理如下:
图五、Launcher第一次创建数据库时,对AppWidget的处理
执行过程:
1.移除掉Launcher作为AppWidgetHost相关的内容;[Seq#4]
2.解析default_workspace.xml中的内容,如果是appwidget相关的:
a)申请AppWidgetId;[Seq#8 ~ #9]
b)把解析出的内容插入TABLE_FAVORITES表单;[Seq#10]
c)把AppWidgetId与AppWidgetProvider绑定;[Seq#11]
其实这个过程就浓缩了用户选择AppWidgetProvider,然后再绑定等等一系列的过程。只是这里的要用哪个AppWidgetProvider,放在哪一屏的哪个位置都在配置里确定了,所以可以直接自动完成。
比如,下面是res/xml/default_workspace.xml中,关于“电量控制”这个AppWidget的配置:
<appwidget launcher:packageName="com.android.settings" launcher:className="com.android.settings.widget.SettingsAppWidgetProvider" launcher:screen="3" launcher:x="0" launcher:y="0" launcher:spanX="4" launcher:spanY="1" />
而要解析default_workspace.xml中AppWidget的哪些属性是由res/values/attrs.xml中的Favorite指定的:
<!-- XML attributes used by default_workspace.xml --> <declare-styleable name="Favorite"> <attr name="className" format="string" /> <attr name="packageName" format="string" /> <attr name="screen" format="string" /> <attr name="x" format="string" /> <attr name="y" format="string" /> <attr name="spanX" format="string" /> <attr name="spanY" format="string" /> <attr name="icon" format="reference" /> <attr name="title" format="reference" /> <attr name="uri" format="string" /> </declare-styleable>
图六、Launcher中的简要数据模型
图七、Launcher数据模型的初始化
执行顺序:
1.Launcher被创建时,Launcher.onCreate()被执行;
2.通过getApplication()获得LauncherApplication;LauncherApplication被创建(launcherApplication.onCreate())时:
a)实例化LauncherModel,并把LauncherApplication自身传进去;
b)为LauncherModel注册广播;
3.通过LauncherApplication的setLauncher()把Launcher自身传进去;
LauncherApplication. setLauncher()调用LauncherModel的initialize()把Launcher这个launcherModel.Callbacks的实例传进去;
4.实例化LauncherAppWidgetHost这个AppWidgetHost,并通过startListening(),把IAppWidgetHost注册进AppWidgetSerivce。
在需要加载数据模型的时,LauncherModel的startLoader()会被执行。LauncherModel开启一个LoaderTask线程,具体执行load和bind的工作。
图八、LauncherModel加载并绑定Workspace
执行加载过程:
1.用LauncherSettings.Favorites.CONTENT_URI查询所有的数据;[Seq#1~ #3]
2.从LauncherSettings.Favorites.ITEM_TYPE字段获取当前记录的类型;[Seq#4~ #7]。
3.对于AppWidget类型(type为LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET),获得AppWidget关注的其他字段,并赋值给LauncherAppWidgetInfo;[Seq#8~ #9]
4.把LauncherAppWidgetInfo的实例加入mAppWidgets;[Seq#10]
执行绑定过程:
通过LauncherModel.Callbacks的实现,也就是Launcher,执行:
执行LauncherModel.Callbacks.bindAppWidget()在Launcher中执行。
图九、Launcher bindAppwidget
这个过程同图二的执行,可参考研读。
本文讲述了:
通过这一系列的其他文章,可获得与本文关联的信息:
AppWidget系统框架。
Launcher发起选取过程,此文中描述选取并绑定的过程,可结合本文看完整的选取/绑定/加入显示系统的完整过程。
Android中AppWidget的分析与应用:AppWidgetProvider
本文所描述的信息,是此文所描述的AppWodgetProvider所提供的。
Android中Launcher对于AppWidget处理的分析:AppWidgetHost角色
本文
RemoteViews的内部如何实现,看如何具体用RemoteViewsupdate AppWidgetHostView。