探秘widget之widget背後的故事

來源:互聯網
上載者:User

                               By 何明桂(http://blog.csdn.net/hmg25) 轉載請註明出處

 

     之前分析了下widget添加到laucher的過程,現在我們來分析下widget被添加到laucher之後發生的故事。

     AppWidgetProvider

 

案頭組件實現的組要類,它的父類是一個廣播接收器,它主要作用就是接收更新案頭組件的廣播訊息,然後更新案頭組件

                         i.              public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds):

該方法對應事件:android.appwidget.action.APPWIDGET_UPDATE當案頭組件被周期更新的時候它被調用,深入父類的onReceive方法就會瞭解到,當父類的onReceive方法接收到android.appwidget.action.APPWIDGET_UPDATE訊息就會調用該update方法。

                       ii.              public void onReceive(Context context, Intent intent):

AppWidgetProvider本身是一個廣播接收器,父類已經覆蓋了該方法,你重新覆蓋該方法的時候,注意要添加super. onReceive到你的方法中,否則onUpdate將不再會被調用

                      iii.              public void onDeleted(Context context, int[] appWidgetIds):

AppWidgetProvider接收訊息android.appwidget.action.APPWIDGET_DELETED時候調用該方法。

 

 

每個案頭組件就是一個AppWidget,當你需要在代碼中實現一個案頭組件,首先你必須得實現AppWidgetProvider類,當你點擊AppWidgetProvider類你會發現其實AppWidgetProvider就是一個BroadcastReceiver子類,也就是說它也是一個廣播接收器。案頭組件內容顯示更新全部是通過RemoteViews對象,剛建立案頭組件的時候系統會綁定AppWidgetProvider到一個AppWidgetId,然後後面通過AppWidgetManager.updateAppWidget方法把RemoteViews對象更新到對應的案頭組件。

 

     回到之前添加widget時的流程,在案頭組件剛被添加的時候,系統通過AppWidgetHost.allocateAppWidgetId函數為案頭組件分配一個新的AppWidgetId。在選擇widget的時候,通過點擊的列表選項可擷取到對應案頭組件對應的ComponentName,一個ComponentName由一個包名和一個AppWidgetProvider類名稱唯一指定,然後通過AppWidgetManager.bindAppWidgetId(int appWidgetId, ComponentName provider)把前面產生的AppWidgetId與一個ComponentName綁定,一個ComponentName可以綁定多個AppWidgetId。所以你可以在案頭上放置幾個一樣的widget。

      一個AppWidgetProvider可以由一個ComponentName唯一確定,在一般的widget應用中:

 

//先擷取一個AppWidgetManager對象<br /> AppWidgetManager appWidgetMgr = AppWidgetManager.getInstance(context);<br />//建立一個ComponentName對象,用來擷取擷取案頭組件widgetIds<br /> ComponentName compName = new ComponentName(context,<br /> ExampleWidgetProvider.class);<br />//返回的是由 ComponentName對應的 int[] widgetIds<br /> int[] widgetIds = appWidgetMgr.getAppWidgetIds(compName); 

每一個AppWidgetProvider上可能建立了多個案頭組件,每一個案頭組件對以應一個AppWidgetId,要擷取一個AppWidgetProvider上所有的案頭組件的AppWidgetId資料,可以先建一個ComponentName對象,設定ComponentName中的類名和包名為AppWidgetProvider的類名和包名,然後可通過AppWidgetManager. getAppWidgetIds(ComponentName provider)方法擷取AppWidgetId列表。

通過AppWidgetId我們便可以操作指定的widget。

    widget介面的更新是通過RemoteViews日哦,而RemoteViews並不是一個真正的View,它沒有實現View的介面,而只是一個用於描述View的實體。比如:建立View需要的資源ID和各個控制項的事件回應程式法。RemoteViews會通過處理序間通訊機制傳遞給AppWidgetHost。

    AppWidgetHost和AppWidgetHostView是在framework中定義的兩個基類。應用程式可以利用這兩個類來實現自己的Host。Launcher是預設的案頭,它是一個Host的實現者。

LauncherAppWidgetHostView擴充了AppWidgetHostView,實現了對長按事件的處理。

LauncherAppWidgetHost擴充了AppWidgetHost,這裡只是重載了onCreateView,建立LauncherAppWidgetHostView的執行個體。

     Remoteviews更新案頭組件最終還是要在launcher進程中執行,在launcher中有一個handler: AppWidgetHost.UpdateHandler,該handler就是用來處理Remoteviews更新的,一旦我們調用appWidgetManager.updateAppWidget(appWidgetId, views)這個方法,AppWidgetHost.UpdateHandler. handleMessage事件就會響應,不過要注意是該事件響應是在launcher進程中執行:

 

 

 

 

 

switch (msg.what) {<br /> case HANDLE_UPDATE: {<br /> updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);//執行Remoteviews更新<br /> break;<br /> } 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.