Android ランタイム リソースの置換----ランタイム リソース オーバーレイの実践

【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 を使用して直接インストールできます。

  1. ターゲット アプリケーションとリソース パッケージを実行する
  2. 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] // 关闭

デモ

公式ドキュメント

おすすめ

転載: blog.csdn.net/jxq1994/article/details/130992767