android 进lanucher的广播,(转)Android中Launcher对于AppWidget处理的分析:AppWidgetHost角色...
圖二的時序圖描述了,從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]
由于override里onCreateView(),onCreateView()被執行。在onCreateView()中創建LauncherAppWidgetHostView;[Seq#8~
#10]
AppWidgetHost.createView()中,把AppWidgetProviderInfo設置到appWidgetHostView里;[Seq#11]
AppWidgetHost.createView()中,通過AppWidgetService獲得AppWidgetProvider提供的RemoteViews【AppWidgetHost、AppWidgetProvider、AppWidgetService運行在不同的進程中,此時不能保證RemoteViews有內容,亦即不能保證AppWidgetProvider.onUpdate()已經被執行】;[Seq#12~
#13]
AppWidgetHost.createView()中,用RemoteViews更新appWidgetHostView;[Seq#14]
返回已創建AppWidgetHostView的實例;[Seq#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第一次創建Database時,處理AppWidget
Launcher的數據庫操作的相關的類
圖四、Launcher的數據庫操作LauncherProvider
Launcher在LauncherProvider中操作數據庫;AppWidget相關項是在TABLE_FAVORITIES表單中;LauncherProvider.AUTHORITY定義操作數據庫的入口,組合了LauncherSettings.Favorites.CONTENT_URI這個Uri來具體操作。
用SQLite具體存儲,所有用SQLiteOpenHelper的子類LauncherProvider.DatabaseHelper來具體操作SQLite數據庫。
數據庫TABLE_FAVORITIES中的具體Filed在LauncherSettings.Favorites中定義。
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的配置:
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指定的:
三、Launcher正常啟動加載數據庫中的AppWidget
3.1 Launcher中的數據模型
圖六、Launcher中的簡要數據模型
LauncherModel是一個BroadcastReceiver;用mCallbacks記錄Model變化時,要通知的對象;mAppWidgets中記錄加入的AppWidget的信息。
Launcher實現LauncherModel.Callbacks,注冊進LauncherModel,當Model變化時,做相應的處理。
3.2 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。
3.3 加載并綁定Workspace
在需要加載數據模型的時,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,執行:
startBinding();
對所有的mAppWidgets中的Widget,執行bindAppWidget()。
執行LauncherModel.Callbacks.bindAppWidget()在Launcher中執行。
3.4 Launcher綁定AppWidget
圖九、Launcher bindAppwidget
這個過程同圖二的執行,可參考研讀。
總結
本文講述了:
Launcher在選擇了一個AppWidgetProvider之后,通過AppWidgetHost創建本地的AppWidgetHostView,用來呈現AppWidgetProvider通過RemoteViews提供的的提供內容。相應的LauncherAppWidgetInfo加入到LauncherModel的數據模型中。
Launcher(AppWidgetHost) / AppWidgetService
/AppWidgetProvider由于運行于不同的進程中,執行的次序不確定使得RemoteViews的內容時效性不定,但是只要RemoteViews有更新,AppWidgetHost就會得到通知而更新。
在系統第一次執行(剛燒機或恢復出廠設置之后)時,數據庫第一次被初始化,會從default_workspace.xml中加載初始的AppWidget信息,并加入到LauncherModel的數據模型中。
在正常開機過程(非剛燒機或恢復出廠設置之后)中,AppWidget的信息被從數據庫中讀取出來,并加入到LauncherModel的數據模型中。
可進一步參考的文章
通過這一系列的其他文章,可獲得與本文關聯的信息:
AppWidget系統框架。
Launcher發起選取過程,此文中描述選取并綁定的過程,可結合本文看完整的選取/綁定/加入顯示系統的完整過程。
本文所描述的信息,是此文所描述的AppWodgetProvider所提供的。
本文
RemoteViews的內部如何實現,看如何具體用RemoteViewsupdate AppWidgetHostView。
總結
以上是生活随笔為你收集整理的android 进lanucher的广播,(转)Android中Launcher对于AppWidget处理的分析:AppWidgetHost角色...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android fragment 退出程
- 下一篇: android grideview 图片