Android中Launcher對於AppWidget處理的分析:AppWidgetHost角色

來源:互聯網
上載者:User

田海立@CSDN

2012-8-21

 

Launcher在Android的AppWidget整個體系中扮演AppWidgetHost的角色,本文分析Launcher對於AppWidget的處理,主要包括:選取AppWidgetProvider之後的處理;Launcher初始化過程中載入(包括第一次載入和之後正常的載入)AppWidget資訊的處理,等。

 

由《Android中選取並綁定AppWidget》中知道,Launcher發起選取操作;Settings中的AppWidgetPickActivity擷取所有已經安裝的AppWidgetProvider,讓使用者選擇,使用者選擇之後,回到啟動它的Activity的onActivityResult()。

 

一、Launcher擷取AppWidget之後的處理

 

先看Launcher中定義的用來處理AppWidget的相關的類:

 


圖一、Launcher中AppWidget的相關類

 

  • Launcher是一個Activity;
  • 繼承AppWidgetHost的LauncherAppWidgetHost用來操作AppWidgetHost功能,overrideonCreateView()用於建立自己的AppWidgetHostView– LauncherAppWidgetHostView;
  • LauncherAppWidgetHostView用來改變點擊操作行為習慣;
  • Launcher把UserFolder/ LiveFolder / AppWidget等做成一定的資料模型,用ItemInfo來抽象,對應AppWidget用LauncherAppWidgetInfo來表達。

 

圖二的時序圖描述了,從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中的具體FiledLauncherSettings.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的配置:

<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正常啟動載入資料庫中的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的資料模型中。

 

可進一步參考的文章

通過這一系列的其他文章,可獲得與本文關聯的資訊:

Android AppWidget架構

    AppWidget系統架構。

Android中選取並綁定AppWidget

    Launcher發起選取過程,此文中描述選取並綁定的過程,可結合本文看完整的選取/綁定/加入顯示系統的完整過程。

Android中AppWidget的分析與應用:AppWidgetProvider

    本文所描述的資訊,是此文所描述的AppWodgetProvider所提供的。

Android中Launcher對於AppWidget處理的分析:AppWidgetHost角色

    本文

Android中RemoteViews的實現

    RemoteViews的內部如何?,看如何具體用RemoteViewsupdate AppWidgetHostView。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.