既に随所で語られているので今更ではありますが、いちいち思い出したり調べなおしたりするのも面倒なので、備忘録としてまとめておきます。
dexとodexについて
AndroidはDalvik VMという独自VMで動いており、javaのclassファイルではなく、低メモリ環境に最適化したdexファイル(Dalvik Executable)を使用します。
dexファイルは、端末内で実行される際に再度最適化(データ構造や関数のインライン展開等)され、odexファイル(Optimized Dalvik Executable)としてキャッシュされます。
odexファイルはVM環境に依存するため、バージョンが異なると、他の環境からコピーしても動作しません。
Androidのアプリケーションは、apkファイル(Android Package)という形式で提供されています。
- /data/app以下のアプリケーション
- /system/app以下のアプリケーション
Android Market等から別途インストールしたものです。
apk内にclasses.dexが含まれており、実行時に/data/dalvik-cache以下にodexキャッシュが自動生成されます。
システムアプリケーションや、プリインストールものです。
apk内にはclasses.dexがない場合が多く、apkと同名のodexが/system/appに存在しています。
これにより、odexキャッシュがdataパーティションに生成されて容量が減ることがありません。
deodex – odexをdexに変換する
/system/appにあるapkには、classes.dexがなく、同名のodexが存在します。
このままでは移植できないので、odexからdexに変換(deodex)し、apkに追加する必要があります。
変換には、dexファイルのassembler/disassemblerであり、odexファイルも扱うことができるsmaliを用います。
- smali/baksmaliの準備
smali – Project Hosting on Google Code から、smali、smali-1.2.4.jar、baksmali、baksmali-1.2.4.jarの4ファイルを取得します。
smali、baksmaliスクリプトが動作するように、jarファイルをリネームします。
% wget http://smali.googlecode.com/files/smali % wget http://smali.googlecode.com/files/smali-1.2.4.jar % wget http://smali.googlecode.com/files/baksmali % wget http://smali.googlecode.com/files/baksmali-1.2.4.jar % mv smali-1.2.4.jar smali.jar % mv baksmali-1.2.4.jar baksmali.jar
これらのファイルを設置したディレクトリにパスを通しておくと便利です。
odexをdisassembleするには、odexが動作するROMの/system/frameworkディレクトリが必要です。(system.imgを展開していれば、中にあるはず)
% baksmali -d system/framework -o Sample -x Sample.odex
これで、disassembleされたsmaliファイルがSampleディレクトリに生成されます。
※-xオプションをつけずにdexファイルを指定すると、dexファイルがdisassembleできます。
% smali -o classes.dex Sample
これで、Sampleディレクトリ以下のsmaliファイルがclasses.dexとしてassembleされます。
apkの実体はzipファイルなので、生成したclasses.dexは
% zip Sample.apk classes.dex
等で、既存のapkファイルに追加できます。しかしながらapkファイルには署名がされているため、そのままでは使用できず、再署名する必要があります。
dexをodexに変換する
/system/app/にapkを設置する予定でodexキャッシュによるdataパーティション圧迫を避けたい場合など、odexファイルを生成したい場合があります。
classes.dex入りで署名済のapkがある場合は、実機にインストールして一度起動すれば、/data/dalvik-cacheにodexファイルが生成されるので、そのまま利用すればよいでしょう。
しかし、毎回これを行うのも面倒なので、Androidソースに含まれるdexopt-wrapperを利用し、コマンドラインで変換をかけることができます。
dexopt-wrapperで使用するapkは、署名の必要がないので、若干作業が楽になります。
- dexopt-wrapperを準備する
ODEX script for unodex’d ROMs – Android @ MoDaCoからzipを取得、展開して中にあるdexopt-wrapperを実機の/dataに転送します。
% adb push dexopt-wrapper /data/ % adb shell chmod 755 /data/dexopt-wrapper
% adb push Sample.apk /data/ % adb shell # cd /data # ./dexopt-wrapper Sample.apk Sample.odex
生成したodexをapkと共に/system/app/に配置するときは、apk内部のclasses.dexは必要ありません。容量削減のためにも削除しておくほうがよいでしょう。
2011年1月27日