Android車両ウィジェットウィジェットの詳細なソースコードの実践的な開発 - Qianli Ma車両フレームワーク開発に関する実践コース

公式サイト参考リンク:https://developer.android.google.cn/develop/ui/views/appwidgets/overview

1. ウィジェットとは何ですか?

アプリ ウィジェットは、他のアプリケーション (ホーム画面など) に埋め込み、定期的に更新を受け取ることができる小型のアプリケーション ビューです。
一般的な説明: 定期的に更新して他のアプリケーションに追加できるミニチュア ビュー。
Android フレームワークのコンテンツの詳細については、Qianlima とプライベートでチャットしてください: https://www.bilibili.com/video/BV1wj411o7A9/

2. ウィジェットの動作メカニズムは何ですか?

ここに画像の説明を挿入しますAppWidgetProviderでウィジェットの動作を定義
RemoteViewとレイアウトファイルでウィジェットのUIを定義
AppWidgetManagerでビューを更新
マニフェストにAppWidgetProvider(ブロードキャストから継承)を登録し、リッスンアクションを設定

3. ウィジェットはどのようなプロセスで実行されますか?

まず、次の図に示すように、ホスト プロセスとウィジェット プロセスを理解しましょう。
ここに画像の説明を挿入します
ウィジェットの操作に関与するプロセスと、各プロセスの責任です。
ここに画像の説明を挿入します

ウィジェットの実行ロジックは 3 つの部分に分割する必要があります。AppWidgetProvider のロジックは、ウィジェットが配置されているアプリケーション プロセスで実行されます。ウィジェットのデータ ストレージ、権限検証のロジック、およびウィジェット プロセスとホスト プロセス間の通信ブリッジ、つまりプロセス間通信の仲介は、system_process で実行されます。ウィジェットのレンダリング ロジックはホスト プロセス内にあります。

4. RemoteView はどのように機能しますか?

RemoteView は Parcelable から継承しており、プロセス間で渡すことができます。RemoteView は、設定された各動作を対応するアクションに変換します。アクションは、ホスト側のプロセス中に対応する動作に変換されます。

例:独自のプロセスで TextView の
通常の
setText メソッドを使用する場合は、mTextView.setText を直接呼び出します。
ただし、このウィジェットは独自のウィジェット プロセスによってレンダリングされません。RemoteView を通じてのみ操作できます。RemoteView の原理は実際には次のとおりです。渡すクラスはメソッド名です。文字列はプロセス間で渡され、ホスト プロセスに到達するため、文字です。ホスト プロセスは、メソッド名の文字列に基づいてリフレクション呼び出しを行うことができます。概略図は次のとおりです

ここに画像の説明を挿入します

RemoteViews は本質的にプロセスをまたがってビューを制御・表示できる媒体であることがわかりますが、自分のビューを制御するほど便利ではありません、ビューに対応する制御インターフェースを 1 つずつ変換する必要があるため、まだ非常に便利ですここで注意してください、ビューには多くの種類がありますが、リモートビューには固定されたものしかなく、任意のビューやカスタマイズはサポートされていません。
ここに画像の説明を挿入します

5. ウィジェット開発部

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 AppWidgetProviderInfo 情報を用意する
AppWidgetProviderInfo は主にウィジェットのレイアウトや更新頻度などのウィジェットのメタデータを記述したもので、一般的には 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>

最も重要なことは、initialLayout が初期化レイアウトを持つということです。これはウィジェットのデフォルトの表示レイアウト、つまり、ウィジェット プログラムが updateWidget コードを呼び出す前に表示されるデフォルトのレイアウトです。

レイアウト/アプリウィジェットプロバイダー

<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 AppWidgetProvider 実装クラスを準備する
AppWidgetProvider の実装クラスは
ブロードキャストに基づいており、更新、有効、無効、その他の通知などの状況を AppWidget に通知するためにコールバックされます。

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    
    

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

3 マニフェストに登録する

     <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>

メタデータ タグも非常に重要で、AppWidgetProviderInfo にリンクされた XML です。

4. コードを通じてウィジェットの 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);
    }

主にレイアウトを通じて対応する RemoteView を構築し、次にレイアウト内の特定のビューに対して関連するセット操作を実行し、最後に appWidgetManager の updateAppWidget メソッドを呼び出して AppWidget を更新します。

関連するデモ アドレスについては、aosp ソース コードをダウンロードする必要があります:
aosp/development/samples/ApiDemos/src/com/example/android/apis/appwidget/

ウィジェットはモバイル デスクトップのウィジェット ページに表示されます。前のウィジェットのマニフェストが構成されているため、デスクトップをスキャンして表示できます。デスクトップに正常にドラッグすると、ウィジェットは次のように表示されます
ここに画像の説明を挿入します

ここに画像の説明を挿入します

6. Widgetの表示Hostプロセスの詳細説明

aosp の CarLauncher では関数コード自体が非常にシンプルで、該当するアプリウィジェットを表示する必要がありませんが、モバイルデスクトップでは完全なコード部分がウィジェットホストとして存在します。したがって、WidgetHost をクリアする方法を理解することが非常に重要になります。

必要

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 は、システム システム サーバーの AppWidget サービスとの対話を担当します。各 AppWidgetHost は独立した ID を持つ必要があります。つまり、デスクトップだけがホストとして使用できるわけではありませんが、最も一般的なのはデスクトップです。複数のホストが存在できること。ウィジェットも表示します
ここに画像の説明を挿入します

アプリ ウィジェット ID は、各アプリ ウィジェット インスタンスが、AppWidgetHost の assignAppWidgetId メソッドを通じて取得される独立した ID を持つことを表します。この ID は主にウィジェットをバインドするときに必要です。つまり、bindAppWidgetIdIfAllowed メソッドにはこの ID が必要です。

AppWidgetHostView は、
ウィジェットをレンダリングするビューとして機能し、ウィジェットの関連ビューをインフレートする役割を果たします。

必要な
BIND_APPWIDGET 権限レベル
ここに画像の説明を挿入しますは次のとおりです: プラットフォームの署名が必要であるか、組み込みの priv/app である必要があります。実際、CarLauncher は通常これで満足しており、プラットフォームの署名は通常システムと同じです。 。

具体的な実際の分析 (aosp のソース コード デモを参照:development/apps/WidgetPreview/src/com/android/widgetpreview/WidgetPreviewActivity.java):

  第一步,根据独特HOST_ID,构造出AppWidgetHost :
  mAppWidgetHost = new AppWidgetHost(getApplicationContext(), APPWIDGET_HOST_ID);
  第二步,AppWidgetHost 申请出独特的widget id:
  int id = mAppWidgetHost.allocateAppWidgetId();
  第三步,用申请的widget id绑定到对应的widget的provider的componentName:
  mAppWidgetManager.bindAppWidgetId(mAppWidgetId, intent.getComponent(), options);
  第四步,获取providerInfo,创建对应的AppWidgetHostView,进行add:
	 AppWidgetProviderInfo providerInfo =
            AppWidgetManager.getInstance(getBaseContext()).getAppWidgetInfo(appWidgetId);
mAppWidgetView = mAppWidgetHost.createView(getBaseContext(), appWidgetId, providerInfo);
mAppWidgetFrame.addView(mAppWidgetView, mPreviewWidth, mPreviewHeight);

ここに画像の説明を挿入します現象のデモンストレーション:
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/learnframework/article/details/132707953