1. ホーム
  2. android

[解決済み] アンドロイドのリソースとリソースIDのマッピングはどのように行われるのですか?

2023-08-28 05:22:30

質問

Android では、このように R.id.XXX .

AFAIK では、リソースはバイナリ形式にコンパイルされていますが、このマッピングロジックは、ボンネットの中でどのように動作しているのでしょうか?

たぶん はこのように動作します。

例えば layout1.xml というのがありますが、私たちは

<Button android:id="@+id/button1" >

で、AAPTはこれをR.javaで生成します。

public static final int button1=0x7f05000b;

を指定すると *.apk が生成されると ボタン1 を "0x7f05000b" に置き換えてください。

このように、呼び出すと

findViewById(R.id.button1);

IDは0x7f05000bのような数字ですが、基本的にはまだIDに基づいて検索を行っています。

ありがとうございます。

追加

私が本当に知りたいのは、リソースIDがどのようにリソースコンテンツにパースされるのか、ということです。言い換えれば、Android ランタイムは、リソース ID を唯一の手がかりとして、どのようにリソース コンテンツを見つけるのでしょうか。

たとえば、描画可能な画像はどのようにしてリソース ID で見つけられるのでしょうか?あるいは、文字列の値はどのようにしてリソースIDで見つけられるのでしょうか?

どのように解決するのですか?

ビルド時に aapt ツールは、あなたが定義したすべてのリソース (個別のファイルまたはファイル内の明示的な定義) を収集し、リソース ID をそれらに割り振ります。

リソース ID は 32 ビットの数字で、次のような形式です。PPTTNNNN。 PP はリソースのパッケージ、TT はリソースのタイプ、NNNN はそのタイプにおけるリソースの名前です。 アプリケーションリソースの場合、PPは常に0x7fです。

TT と NNNN の値は aapt によって任意に割り当てられます。基本的に、それぞれの新しい型に対して、次に利用可能な番号が割り当てられ使用されます (1 から始まります)。同様に、それぞれの型の中の新しい名前に対して、次に利用可能な番号が割り当てられ使用されます (1 から始まります).

ですから、もしこれらのリソースファイルが aapt によってこの順番で処理されるとしたら。

layout/main.xml
drawable/icon.xml
layout/listitem.xml

最初に表示されるタイプは "layout"なので、TT == 1 が与えられます。 その型の下の最初の名前は "main" なので、NNNN == 1 が与えられています。 最終的なリソース ID は 0x7f010001 です。

次に、"drawable" があるので、これには TT == 2 が与えられます。 このタイプの最初の名前は "icon" なので、NNNN == 1 が与えられます。 最終的なリソース ID は 0x7f020001 です。

最後に、別の "layout" が表示され、先ほどと同様に TT == 1 となります。 これは新しい名前 "listitem" を持つので、次の値 NNNN == 2 を取得します。 最終的なリソース ID は 0x7f010002 です。

aapt はデフォルトで、ビルド間でこれらの識別子を同じにすることを試みないことに注意してください。 リソースが変更されるたびに、それらはすべて新しい識別子を取得することができます。 ビルドされるたびに、新しい R.java が現在の識別子で作成され、コードが正しい値を取得するようになります。 このため、リソースの識別子を、アプリの異なるビルド間で使用できる場所に永続化させてはいけません。

リソースがコンパイルされ識別子が割り当てられると、apt はソースコード用の R.java ファイルと、リソース名、識別子、および値をすべて含む "resources.arsc" というバイナリファイルを生成します (別のファイルから来るリソースについては、値は .apk のそのファイルへのパスとなります)。

apk 内の resources.arsc ファイルの要約は、 "aapt dump resources <path-to-apk>" コマンドで取得することができます。

バイナリリソーステーブルのフォーマットは、ここのリソースデータ構造用のヘッダーファイルで文書化されています。

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/include/androidfw/ResourceTypes.h

デバイス上のリソーステーブルを読み込むための完全な実装はこちらです。

https://github.com/android/platform_frameworks_base/blob/master/libs/androidfw/ResourceTypes.cpp