最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

android 車載widget小部件部分詳細源碼實戰(zhàn)開發(fā)-千里馬車載車機framework實戰(zhàn)開發(fā)

2023-09-05 10:52 作者:千里馬學(xué)框架  | 我要投稿

官網(wǎng)參考鏈接:https://developer.android.google.cn/develop/ui/views/appwidgets/overview[1]

1、什么是小部件

App widgets are miniature application views that can be embedded in other applications (such as the home screen) and receive periodic updates。 通俗解釋:一個能夠定期刷新并且加到其他應(yīng)用上的微型視圖。

更多android framework干貨內(nèi)容請找千里馬微信私聊:


2、小部件的運行機制是什么?

在這里插入圖片描述

通過 AppWidgetProvider 定義小部件的行為 通過 RemoteView 和布局文件定義小部件的UI 通過AppWidgetManager 更新視圖 在manifeset 里注冊 AppWidgetProvider(繼承于廣播),設(shè)置監(jiān)聽的action

3、小部件運行在什么進程?

首先明白一下Host進程和widget進程,看如下圖所示:

在這里插入圖片描述

小部件運行波及的進程,及各個進程的責(zé)任:

在這里插入圖片描述

小部件的運行邏輯需要分為三部分:AppWidgetProvider 中的邏輯運行在小部件所在應(yīng)用進程。小部件的數(shù)據(jù)存儲,權(quán)限校驗的邏輯,widget進程和host進程的溝通橋梁即跨進程通訊中介,運行在system_process中。小部件渲染邏輯在host 進程中。

4、RemoteView如何工作?

RemoteView 繼承于Parcelable,可在進程間傳遞。RemoteView 會將每一個設(shè)置的行為轉(zhuǎn)換成相應(yīng)的Action。在Host 側(cè)進程時再將Action 翻譯成對應(yīng)的行為。

如: 正常自己進程 TextView 的setText方法,直接調(diào)mTextView.setText就行 但是這個widget都不是自己widget進程進行的渲染,這里就只能通過RemoteView方式來操作,RemoteView的原理其實就是,傳遞類是一個方法名字字符,因為字符串是可以跨進程傳遞的,然后到達了Host進程,Host進程可以根據(jù)方法名字的字符串進行反射調(diào)用 原理圖如下:

在這里插入圖片描述

可以看出RemoteViews本質(zhì)就是個可以進行跨進程控制顯示view的媒介,沒有像控制自己view那么的方便,對應(yīng)view的控制接口都需要一一轉(zhuǎn)化,所以還是很不靈活,而且這里注意了,因為view種類可能很多,但是remoteviews就只有固定一些,不支持隨意各種view或者自定義

在這里插入圖片描述

5、widget開發(fā)部分

AppWidgetProviderInfo?object?
Describes?the?metadata?for?an?App?Widget,?such?as?the?App?Widget's?layout,?update?frequency,?and?the?AppWidgetProvider?class.?This?should?be?defined?in?XML.
AppWidgetProvider?class?implementation
Defines?the?basic?methods?that?allow?you?to?programmatically?interface?with?the?App?Widget,?based?on?broadcast?events.?Through?it,?you?will?receive?broadcasts?when?the?App?Widget?is?updated,?enabled,?disabled?and?deleted.

1 準(zhǔn)備好AppWidgetProviderInfo信息 AppWidgetProviderInfo 主要來描述Widget的元數(shù)據(jù),比如widget的layout,更新頻率,一般在xml中進行定義

<appwidget-provider?xmlns:android="http://schemas.android.com/apk/res/android"
????android:minWidth="60dp"
????android:minHeight="30dp"
????android:updatePeriodMillis="86400000"
????android:initialLayout="@layout/appwidget_provider"
????android:configure="com.example.android.apis.appwidget.ExampleAppWidgetConfigure"
????android:resizeMode="horizontal"
????>

</appwidget-provider>

最關(guān)鍵的是initialLayout會有初始化布局,即widget默認顯示布局,即widget程序如果還沒有調(diào)用代碼的updateWidget前顯示的默認布局

layout/appwidget_provider

<TextView?xmlns:android="http://schemas.android.com/apk/res/android"
????android:id="@+id/appwidget_text"
????android:layout_width="wrap_content"
????android:layout_height="wrap_content"
????android:background="#ffff00ff"
????android:textColor="#ff000000"
/>

2 準(zhǔn)備好AppWidgetProvider實現(xiàn)類 AppWidgetProvider的實現(xiàn)類 以廣播為基礎(chǔ),回調(diào)通知AppWidget情況,比如更新,enable,disabled等通知

public?class?ExampleAppWidgetProvider?extends?AppWidgetProvider?{

????@Override
????public?void?onUpdate(Context?context,?AppWidgetManager?appWidgetManager,?int[]?appWidgetIds)?
{
????????//省略
????}
????//省略
}

3 在manifest中進行注冊

?????<receiver?android:name=".appwidget.ExampleAppWidgetProvider">
????????????<meta-data?android:name="android.appwidget.provider"
????????????????????android:resource="@xml/appwidget_provider"?/>

????????????<intent-filter>
????????????????<action?android:name="android.appwidget.action.APPWIDGET_UPDATE"?/>
????????????</intent-filter>
????????</receiver>

meta-data標(biāo)簽也非常重要,它就是鏈接上了AppWidgetProviderInfo的xml

4 widget的ui通過代碼更新方式

??static?void?updateAppWidget(Context?context,?AppWidgetManager?appWidgetManager,
????????????int?appWidgetId,?String?titlePrefix)
?
{

????????RemoteViews?views?=?new?RemoteViews(context.getPackageName(),?R.layout.appwidget_provider);
????????views.setTextViewText(R.id.appwidget_text,?text);

????????//?Tell?the?widget?manager
????????appWidgetManager.updateAppWidget(appWidgetId,?views);
????}

主要通過布局構(gòu)建出對應(yīng)的RemoteViews,然后對布局中的具體View進行相關(guān)set操作,最后調(diào)用appWidgetManager的updateAppWidget方法進行更新AppWidget

相關(guān)demo地址,需要下載aosp源碼: aosp/development/samples/ApiDemos/src/com/example/android/apis/appwidget/

widget展示在手機桌面的widget頁面,因為前面的widget的manifest配置了,所以桌面才可以掃描展示出來:

在這里插入圖片描述

拖動到桌面成功后widget顯示如下:

在這里插入圖片描述

6、Widget的顯示Host進程詳解

在aosp的CarLauncher中其實本身功能代碼屬于很簡單,沒有相關(guān)appwidget顯示的需求點,但是是手機桌面是有完整的作為widgethost的代碼部分。所以了解清除怎么作為一個WidgetHost就變得非常關(guān)鍵了。

需要

App?widget?host:?The?AppWidgetHost?provides?the?interaction?with?the?AppWidget?service?for?apps?that?want?to?embed?app?widgets?in?their?UI.?An?AppWidgetHost?must?have?an?ID?that?is?unique?within?the?host's?own?package.?This?ID?remains?persistent?across?all?uses?of?the?host.?The?ID?is?typically?a?hard-coded?value?that?you?assign?in?your?application.

App?widget?ID:?Each?widget?instance?is?assigned?a?unique?ID?at?the?time?of?binding?(see?bindAppWidgetIdIfAllowed(),?covered?in?more?detail?in?Binding?widgets?on?this?page.?The?unique?ID?is?obtained?by?the?host?using?allocateAppWidgetId().?This?ID?is?persistent?across?the?lifetime?of?the?widget,?that?is,?until?it?is?deleted?from?the?host.?Any?host-specific?state?(such?as?the?size?and?location?of?the?widget)?should?be?persisted?by?the?hosting?package?and?associated?with?the?app?widget?ID.

App?widget?host?view:?Think?of?AppWidgetHostView?as?a?frame?that?the?widget?is?wrapped?in?whenever?it?needs?to?be?displayed.?A?widget?is?associated?with?an?AppWidgetHostView?every?time?the?widget?is?inflated?by?the?host.?Note?the?following?points:

By?default,?the?system?will?create?an?AppWidgetHostView,?but?the?host?can?create?its?own?subclass?of?AppWidgetHostView?by?extending?it.
Starting?in?Android?12?(API?level?31),?AppWidgetHostView?introduces?the?the?setColorResources()?and?resetColorResources()?methods?for?handling?dynamically?overloaded?colors.?The?host?is?responsible?for?providing?the?colors?to?these?methods.
AppWidgetHost ?負責(zé)和系統(tǒng)systemserver的AppWidget service進行相關(guān)的交互,每個AppWidgetHost需要有獨立的id,也就意味者其實不僅僅只有桌面可以作為host,只是我們平常最常見是桌面,也代表可以有多個host同時顯示widget

在這里插入圖片描述

App widget ID代表每個App Widget實例都會有個獨立的id,通過AppWidgetHost的allocateAppWidgetId的方法來獲取,主要是在對widget進行binding時候需要這個id,就是bindAppWidgetIdIfAllowed方法需要這個id。

AppWidgetHostView作為渲染widget的view,負責(zé)inflate widget的相關(guān)view

需要權(quán)限BIND_APPWIDGET權(quán)限級別如下:

在這里插入圖片描述

需要有platform簽名,或者屬于內(nèi)置priv/app才可以,這點其實CarLauncher一般都是滿足的,一般都是platform簽名和系統(tǒng)一樣。

具體實戰(zhàn)分析(參考aosp的源碼demo:development/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java):

??第一步,根據(jù)獨特HOST_ID,構(gòu)造出AppWidgetHost?
??mAppWidgetHost?=?new?AppWidgetHost(getApplicationContext(),?APPWIDGET_HOST_ID);
??第二步,AppWidgetHost?申請出獨特的widget?id
??int?id?=?mAppWidgetHost.allocateAppWidgetId();
??第三步,用申請的widget?id綁定到對應(yīng)的widgetprovidercomponentName
??mAppWidgetManager.bindAppWidgetId(mAppWidgetId,?intent.getComponent(),?options);
??第四步,獲取providerInfo,創(chuàng)建對應(yīng)的AppWidgetHostView,進行add
?????AppWidgetProviderInfo?providerInfo?=
????????????AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId);
mAppWidgetView?=?mAppWidgetHost.createView(getBaseContext(),?appWidgetId,?providerInfo);
mAppWidgetFrame.addView(mAppWidgetView,?mPreviewWidth,?mPreviewHeight);

在這里插入圖片描述

現(xiàn)象演示:

在這里插入圖片描述

引用鏈接

[1] 官網(wǎng)參考鏈接:https://developer.android.google.cn/develop/ui/views/appwidgets/overview: https://developer.android.google.cn/develop/ui/views/appwidgets/overview
[2] 更多android framework干貨內(nèi)容請找千里馬私聊:https://www.bilibili.com/video/BV1wj411o7A9/: https://www.bilibili.com/video/BV1wj411o7A9/


android 車載widget小部件部分詳細源碼實戰(zhàn)開發(fā)-千里馬車載車機framework實戰(zhàn)開發(fā)的評論 (共 條)

分享到微博請遵守國家法律
新和县| 璧山县| 晴隆县| 河源市| 天长市| 图们市| 晋州市| 合山市| 北流市| 无极县| 彩票| 郯城县| 固始县| 汕头市| 云和县| 子长县| 大港区| 柘荣县| 石河子市| 锡林浩特市| 徐闻县| 普安县| 大石桥市| 弋阳县| 贵定县| 广南县| 江油市| 叶城县| 繁峙县| 孟津县| 恩平市| 罗定市| 荥经县| 图们市| 青冈县| 磴口县| 东阿县| 张家港市| 开化县| 方山县| 观塘区|