Android AppWidget

Read The Fucking Source Code

引言
  • Android AppWidget相對偏冷門垒在。
  • 開門見山一張圖梦湘,復雜問題庖解牛。


    Android AppWidget 整體架構(gòu)圖

1. AppWidget簡介

  • Android widget 也稱為桌面插件能耻,其是android系統(tǒng)應用開發(fā)層面的一部分合砂,但是又有特殊用途,而且會成為整個android系統(tǒng)的亮點锯七。Android中的AppWidget與google widget和中移動的widget并不是一個概念链快,這里的AppWidget只是把一個進程的控件嵌入到別外一個進程的窗口里的一種方法。
  • AppWidget的服務核心在AppWidgetService中眉尸,它是系統(tǒng)應用域蜗,在SystemServer進程中巨双。
  • AppWidget的提供方由應用提供(對大部分應用開發(fā)者來說,了解操作這一塊就夠了)霉祸。
  • AppWidget的顯示方筑累,基本上運行在Launcher中。
  • AppWidget支持的控件是由局限性的丝蹭,比如不支持RecyclerView等慢宗。
  • RemoteViews 在Android中的使用場景主要有:自定義通知欄和桌面小部件。

2. AppWidget提供方

2.1 XML <appwidget-provider>

  • minHeight半夷、minWidth 定義Widget的最小高度和最小寬度(Widget可以通過拉伸來調(diào)整尺寸大衅爬取)。
  • previewImage 定義添加小部件時顯示的圖標巫橄。
  • initialLayout 定義了小部件使用的布局淘邻。
  • updatePeriodMillis 定義小部件自動更新的周期,單位為毫秒湘换。
  • resizeMode 指定了 widget 的調(diào)整尺寸的規(guī)則宾舅。可取的值有: “horizontal”, “vertical”, “none”彩倚〕镂遥“horizontal"意味著widget可以水平拉伸,“vertical”意味著widget可以豎值拉伸帆离,“none”意味著widget不能拉伸蔬蕊;默認值是"none”。
  • widgetCategory 指定了 widget 能顯示的地方:能否顯示在 home Screen 或 lock screen 或 兩者都可以哥谷。它的取值包括:“home_screen” 和 “keyguard”岸夯。Android 4.2 引入。

2.2 AppWidgetProvider重載方法

  • onUpdate()當Widget被添加或者被更新時會調(diào)用該方法们妥。上邊我們提到通過配置updatePeriodMillis可以定期更新Widget猜扮。但是當我們在widget的配置文件中聲明了android:configure的時候,添加Widget時則不會調(diào)用onUpdate方法监婶。
  • onAppWidgetOptionsChanged()這個方法會在添加Widget或者改變Widget的大小時候被調(diào)用旅赢。在這個方法中我們還可以根據(jù)Widget的大小來選擇性的顯示或隱藏某些控件。
  • onDeleted(Context, int[])當控件被刪除的時候調(diào)用該方法惑惶。
  • onEnable(Context) 第一個加入到屏幕上煮盼。
  • onDisabled(Context)最后一個widget從屏幕移除。
  • onReceive(Context, Intent) 當接收到廣播的時候會被調(diào)用带污。

2.3 AppWidgetProvider的使用經(jīng)驗

  • 作為AppWidgetProvider的實現(xiàn)者僵控,一定要實現(xiàn)onUpdate函數(shù),因為這個函數(shù)決定widget的顯示方式刮刑,如果沒有這個函數(shù)widget根本沒辦法出現(xiàn)喉祭。
  • onUpdate的實現(xiàn)基本上遵循下面的流程:
    • 創(chuàng)建RemoteViews养渴。
    • 調(diào)用AppWidgetManager的updateAppWidget去更新widget。

3. AppWidget顯示方

3.1 AppWidgetHost

  • AppWidgetHost 是實際控制widget的地方泛烙,大家注意理卑,widget不是一個單獨的用戶界面程序,他必須寄生在某個程序(activity)中蔽氨,這樣如果程序要支持widget寄生就要實現(xiàn)AppWidgetHost藐唠。
  • 它的主要功能有兩個:
    • 監(jiān)聽來自AppWidgetService的事件。
    • 另外一個功能就是創(chuàng)建AppWidgetHostView鹉究。
  • RemoteViews不是真正的View宇立,只是View的描述,而 AppWidgetHostView才是真正的View自赔。這里先創(chuàng)建AppWidgetHostView妈嘹,然后通過AppWidgetService查詢 appWidgetId對應的RemoteViews,最后把RemoteViews傳遞給AppWidgetHostView去updateAppWidget绍妨。
  • AppWidgetHost和AppWidgetHostView是在框架中定義的兩個基類润脸。應用程序可以利用這兩個類來實現(xiàn)自己的Host。Launcher是缺省的桌面他去,它是一個Host的實現(xiàn)者毙驯。
  • AppWidgetHostView是真正的View,但它只是一個容器灾测,用來容納實際的AppWidget的View爆价。這個AppWidget的View是根據(jù)RemoteViews的描述來創(chuàng)建。

3.2 Launcher3中對widget的使用理解

  • Launcher3對所有widget的遍歷是在AppWidgetManagerCompat及其子類中媳搪。
  • 通過AppWidgetManager的getInstalledProvidersForProfile / getInstalledProvidersForPackage(Android版本差異)铭段,獲取到AppWidgetProviderInfo的集合。
  • LauncherAppWidgetHost負責監(jiān)聽更新更新和創(chuàng)建LauncherAppWidgetHostView蛾号。
  • LauncherAppWidgetHostView擴展了AppWidgetHostView稠项,實現(xiàn)了對長按事件的處理涯雅。
  • LauncherAppWidgetHost擴展了AppWidgetHost鲜结,這里只是重載了onCreateView,創(chuàng)建LauncherAppWidgetHostView的實例活逆。

3.3 Launcher3核心代碼

Launcher3核心代碼-按需遍歷Widget集合
Launcher3核心代碼-Widget的監(jiān)聽生成

4. AppWidget服務方

4.1 服務框架

  • AppWidgetService是框架的的核心類精刷,是系統(tǒng) service之一,它負責widgets的管理工作蔗候。加載怒允,刪除,定時事件等都需要AppWidgetService的處理锈遥。開機自啟動的纫事。
  • AppWidgetService存在的目的主要是解開AppWidgetProvider和AppWidgetHost之間的耦合勘畔。如果 AppWidgetProvider和AppWidgetHost的關系固定死了,AppWidget就無法在任意進程里顯示了丽惶。而有了 AppWidgetService炫七,AppWidgetProvider根本不需要知道自己的AppWidget在哪里顯示了。
  • AppWidgetManager 負責widget視圖的實際更新以及相關管理钾唬。

5. 我對整體AppWidget的理解

AppWidgetProvider中的onUpdate()參數(shù)appWidgetIds為什么是個數(shù)組?

  • 我的理解是:一個AppWidgetProvider可能被多個地方使用万哪,可能會有幾個實例存在,數(shù)組就是對應的多個實例的存在場景抡秆,可以進行區(qū)分更新奕巍。但是一般來說,只會有一個儒士。

AppWidget的更新過程可以說的通俗一點嗎的止?

  • Widget更新:提供方把應用信息 + RemoteViews包裝好發(fā)給發(fā)給服務方(這些只是信息結(jié)構(gòu)體,其實并不是View)着撩,顯示方監(jiān)聽從服務方的回調(diào)冲杀,在回調(diào)中可以拿到這些信息結(jié)構(gòu)體。
  • 理解方式:雖然我們的目的是更新View睹酌,但是我們不能用更新View的思路去理解权谁,只能用更新Data的思路去理解。
  • 馬夫與馬:更新頻繁當然不好憋沿,因為雖然在應用提供方不涉及View的頻繁加載旺芽,但是在顯示方(要通過數(shù)據(jù)結(jié)構(gòu)生成View),這就是系統(tǒng)原生為什么把AppWidget 的被動刷新頻率下限設定為半小時辐啄。就怕馬夫(提供方)趕馬(顯示方)采章,馬累死了。

RemoteViews的理解

  • RemoteViews并不是一個真正的View壶辜,它沒有實現(xiàn)View的接口悯舟,而只是一個用于描述View的實體。比如:創(chuàng)建View需要的資源ID和各個控件的事件響應方法砸民。RemoteViews會通過進程間通信機制傳遞給AppWidgetHost抵怎。
  • 現(xiàn)在我們可以看出,Android中的AppWidget與google widget和中移動的widget并不是一個概念岭参,這里的AppWidget只是把一個進程的控件嵌入到別外一個進程的窗口里的一種方法反惕。View在另 外一個進程里顯示,但事件的處理方法還是在原來的進程里演侯。

全流程處理時序簡單說明姿染。

  • AppWidgetService啟動:SystemServer服務,開機啟動秒际。
  • AppWidgetProviderInfo獲取:AppWidgetService通過PMS針對注冊了ACTION_APPWIDGET_UPDATE("android.appwidget.action.APPWIDGET_UPDATE")的靜態(tài)廣播進行掃描查詢悬赏。
  • meta-data解析:查詢到的就是AppWidget狡汉,然后從其配置的meta-data中的"appwidget-provider"對應的xml文件開始解析生成AppWidgetProviderInfo結(jié)構(gòu)體。
  • Launcher3獲取Widget信息:Launcher通過AppWidgetManager向AppWidgetService按需拿到所有的AppWidget信息,可以進行展示闽颇。
  • Launcher3顯示W(wǎng)idget信息:Launcher創(chuàng)建AppWidgetHost轴猎,通過上面拿到的Widget信息生成對應的AppWidgetHostView進行展示。
  • Launcher3更新Widget信息:AppWidgetHost創(chuàng)建監(jiān)聽AppWidgetService的更新进萄,進行接收回調(diào)顯示更新捻脖。
  • AppWidget被動刷新:AppWidgetService會根據(jù)AppWidgetProviderInfo的配置維持一個30分鐘下限的更新時鐘,來給AppWidgetProvider來發(fā)送更新通知中鼠。
  • AppWidget主動刷新:應用側(cè)可以拿到AppWidgetManager來進行主動刷新可婶。

6. 附錄(Framework層的代碼路徑及結(jié)構(gòu))

提供方-顯示方-代碼碼路徑
服務方-代碼路徑

?

小編的博客系列

Android Framework 全家桶
?

優(yōu)秀博客推薦

Android官網(wǎng)
Android列表小部件(Widget)開發(fā)詳解
Android UI組件----AppWidget控件入門詳解
Android之AppWidget(桌面小部件)開發(fā)淺析
Android之Widget
Android中Launcher對于AppWidget處理的分析:AppWidgetHost角色
Android widget使用心得
Android Widget小組件開發(fā)(一)
android開發(fā)之widget控件突然停止更新的原因

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市援雇,隨后出現(xiàn)的幾起案子矛渴,更是在濱河造成了極大的恐慌,老刑警劉巖惫搏,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件具温,死亡現(xiàn)場離奇詭異,居然都是意外死亡筐赔,警方通過查閱死者的電腦和手機铣猩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來茴丰,“玉大人达皿,你說我怎么就攤上這事』呒纾” “怎么了峦椰?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長汰规。 經(jīng)常有香客問我汤功,道長,這世上最難降的妖魔是什么溜哮? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任滔金,我火速辦了婚禮,結(jié)果婚禮上茬射,老公的妹妹穿的比我還像新娘鹦蠕。我一直安慰自己冒签,他們只是感情好在抛,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著萧恕,像睡著了一般刚梭。 火紅的嫁衣襯著肌膚如雪肠阱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天朴读,我揣著相機與錄音屹徘,去河邊找鬼。 笑死衅金,一個胖子當著我的面吹牛噪伊,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播氮唯,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼鉴吹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惩琉?” 一聲冷哼從身側(cè)響起豆励,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瞒渠,沒想到半個月后良蒸,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡伍玖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年嫩痰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片窍箍。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡始赎,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出仔燕,到底是詐尸還是另有隱情造垛,我是刑警寧澤,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布晰搀,位于F島的核電站五辽,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏外恕。R本人自食惡果不足惜杆逗,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鳞疲。 院中可真熱鬧罪郊,春花似錦、人聲如沸尚洽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至癣疟,卻和暖如春挣柬,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背睛挚。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工邪蛔, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人扎狱。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓侧到,卻偏偏與公主長得像,于是被迫代替她去往敵國和親淤击。 傳聞我的和親對象是個殘疾皇子床牧,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容