【Car Android】アプリケーションスキニングソリューション(1) - ランタイムリソースオーバーレイより転載
Android は、M 以降、動的リソース オーバーレイ メカニズムであるランタイム リソース オーバーレイ (RRO) を追加しました。これは Sony によって提供されました。実装メカニズムは以下に示すとおりです。フレームワーク内に一連のリソース ID マッピング テーブルを確立し、異なるリソース ID マッピング テーブルを動的に切り替えることです。このマッピング テーブルを通じてテーマを決定します。
RRO スキン リサーフェシングの実践
まず、再スキンする必要があるアプリケーションを準備します。ここでは、例として新しい APP を作成します。以下では、新しいターゲット アプリ プロジェクトを「ターゲット アプリケーション」と呼びます。目標は、RRO メカニズムを使用してカラー値を置き換えることです。ターゲットアプリケーションで。
ステップ 1: リソース パッケージを作成し、AndroidManifest.xml を構成する
まず、新しい独立したアプリ プロジェクトを作成する必要があります。このアプリケーションの目的は、「ターゲット アプリケーション」のリソース ファイルを配置することです。以下、これを「リソース パッケージ」と呼びます。これはアプリケーション プロジェクトですが、ロジック コードは含まれておらず、リソース ファイルを保存するためにのみ使用できます。
このステップに注目して、実際に 2 つの新しいアプリ プロジェクトを作成しました。1 つはターゲット アプリケーションで、もう 1 つはリソース パッケージです。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.target.overlay.ten">
<overlay
android:targetName="ThemeResources"
android:priority="20"
android:targetPackage="com.android.target" />
<application android:hasCode="false"/>
</manifest>
APK の AndroidManifest.xml にタグの子<overlay>
としてタグが含まれている場合<manifest>
、APK は「リソース パッケージ」とみなされます。
- 【必須設定】 android:targetPackage は、RRO が置き換えたい「対象アプリケーション」を指定するために使用されます。
- 【必須設定】 android:hasCode を false に設定する必要があります。コードを置き換えることができないため、RRO は DEX ファイルを使用できません。
- [必須ではない設定] android:targetName は、RRO「ターゲット アプリケーション」の置き換え可能なリソース サブセットの名前を指定するために使用されます。「ターゲットアプリケーション」が代替リソースセットを定義していない場合、この属性を設定する必要はありません。
交換可能なリソースセット
Android 10 以降では、「ターゲット アプリケーション」は
<overlayable>
タグを使用して、RRO 置換を許可するリソースのセットを公開できます。公開されていないリソースについては RRO 置換は許可されません。
<resources>
<overlayable name="ThemeResources">
<policy type="public">
<item type="color" name="purple_200" />
<item type="color" name="purple_500" />
</policy>
</overlayable>
</resources>
APK では複数のタグを定義できますが、各タグにはパッケージ内で一意の名前が必要です。例えば:
- 2 つの異なるリソース パッケージを同時に定義できます。
- APK には 2 つのブロックを含めることはできません。
次に、リソース パッケージの AndroidManifest.xml で targetName を使用して ThemeResources を指定する必要があります。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.target.overlay.ten">
<overlay
android:targetName="ThemeResources"
android:targetPackage="com.android.target" />
<application android:hasCode="false"/>
</manifest>
ターゲット アプリケーションが<overlayable>
タグを定義する場合、リソース バンドルは<overlay>
次の条件を満たす必要があります。
-
targetName を指定する必要があります。
-
<overlayable>
タグにリストされているリソースのみを置換できます。 -
<overlayable>
ターゲットにできる名前は1 つだけです。
制限ポリシー
タグを使用して、<policy>
ターゲット アプリケーション内の置換可能なリソースに制限を課します。type
プロパティは、含まれているリソースを置き換えるためにオーバーレイが満たさなければならないポリシー要件を指定します。次のタイプがサポートされています。
- public: オーバーレイは、対応するリソースを置き換えることができます。
- system: システム パーティション上のオーバーレイは、対応するリソースを置き換えます。
- ベンダー: ベンダー パーティション上のオーバーレイは、対応するリソースを置き換えます。
- product: product パーティション上のオーバーレイは、対応するリソースを置き換えます。
- 署名: ターゲット APK と同じ署名で署名されたオーバーレイは、対応するリソースを置き換えることができます。
<overlayable name="ThemeResources">
<policy type="vendor" >
<item type="string" name="foo" />
</policy>
<policy type="product|signature" >
<item type="string" name="bar" />
<item type="string" name="baz" />
</policy>
</overlayable>
複数のポリシーを指定するには、区切り文字としてパイプ (|) を使用します。複数のポリシーが指定されている場合、オーバーレイは、<policy>
タグにリストされているリソースを置き換えるための 1 つのポリシーの要件を満たすだけで済みます。
ステップ 2: リソース マッピングを定義する
- Android 10 以前
Android 10 以前では、システムは名前に基づいてリソースを置換するため、リソース パッケージ内で置換する必要があるリソースを定義するだけで済みます。
- Android 11 以降Android 11 以降では、Googleは、上書きする必要がある「ターゲット アプリケーション」のリソース値とその置換値を列挙する
ファイルを「リソース パッケージ」の res/xml ディレクトリに作成することを推奨していますoverlays.xml
。
<?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 更换颜色 -->
<item target="color/purple_200" value="#000000"/>
<item target="color/purple_500" value="#000000"/>
<item target="color/purple_700" value="#000000"/>
<item target="color/teal_200" value="#000000"/>
<item target="color/teal_700" value="#000000"/>
<item target="color/black" value="#000000"/>
<item target="color/white" value="#000000"/>
</overlay>
ターゲットタグ内の色には@マークが付いておらず、実際には単なる文字列であり、参照ではないことに注意してください。
次に、リソース バンドルの AndroidManifest.xml 内のリソース マッピング ファイルに android:resourcesMap 属性の値を設定します。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.target.overlay.eleven">
<overlay
android:targetName="ThemeResources"
android:targetPackage="com.android.target"
android:resourcesMap="@xml/overlays"/>
<application
android:hasCode="false"/>
</manifest>
ステップ 3: リソース パッケージをビルドする
ビルドされたリソース パッケージは、以下に示すように、デバッグ時に Android Studio を使用して直接インストールできます。
- ターゲット アプリケーションとリソース パッケージを実行する
- data/app ディレクトリを右クリックし、「同期」オプションを選択します。
上記の 2 つの手順を完了すると、data/app ディレクトリにさらに 2 つのパスが作成され、それぞれターゲット アプリケーションの apk とリソース パッケージを表します。
正式リリース時には「リソースパッケージ」をvendor/overlayディレクトリにリリースし、「ターゲットアプリケーション」をニーズに応じて柔軟に配置することが可能です。次に、Android システムを再起動します。
ステップ 4: RRO を有効/無効にする
RRO は、OverlayManager が提供する API を使用して有効または無効にすることができます。OverlayManager はパブリック Android SDK では提供されていません。Gradle を使用してプロジェクトをビルドする場合は、AOSP ソース コードを使用して Framework.jar をコンパイルし、使用する前にインポートする必要があります。同時に、アプリケーションの署名もまた、アプリケーションをシステムレベルのアプリケーションにするために Android システム署名を使用する必要もあります。
OverlayManager manager = MainActivity.this.getSystemService(OverlayManager.class);
OverlayInfo overlayInfo = manager.getOverlayInfo("com.android.target.overlay.ten", UserHandle.CURRENT_OR_SELF);
manager.setEnabled("com.android.target.overlay.ten", !overlayInfo.isEnabled(), UserHandle.CURRENT_OR_SELF);
RRO を有効または無効にすると、構成変更イベントがターゲット アプリケーションに伝播され、ターゲット アプリケーションのアクティビティが再開されます。
携帯電話でテストする場合は、adb コマンドを使用して RRO のオンとオフを切り替えることができます。
adb shell cmd overlay enable [com.android.target.overlay.ten] // 开启
adb shell cmd overlay disable [com.android.target.overlay.ten] // 关闭