先日開催されたAndroid Dev Summit'19の中の"Shrinking Your App with R8"というYoutube動画をきっかけに、Androidアプリのコード圧縮ツールであるR8について調べていたのですが、その中で出てくるdexについて完全に忘れていたので復習しました。
結論
まず結論から言うと、大雑把に表現するならば、**Java(Kotlin)ファイルをAndroid環境で実行可能な形式に変換圧縮したものがdexファイル(classes.dex)**です。
R8とdex
そもそもR8ってなんだっけ?という点については、上記の動画を更にサマリーしたスライドを作成したので、そちらをご参照ください。
で、Google Developerによると、
R8 により、desugar、圧縮、難読化、最適化、dex 変換(D8)がすべて 1 つのステップで完了します。
と書いてあります。
今回は、このdex 変換という言葉で使われているdexについて簡単にまとめました。
dexの由来
まずdexという名称なのですが、これはDalvik Executableの略です※1。
「Dalvikで実行可能な」的なニュアンスかと思いますが、このDalvikというのはランタイムのことで、Dalvikランタイムで実行可能なファイルという意味合いだと思います。
ちなみにDalvikランタイムというのは現状のAndroidのランタイム(Androidランタイム・ART)の前のランタイムです※2。
APKの中にdexが含まれている
Androidアプリをビルドした時に生成されるapk(Android Package)はzip形式のファイルなのですが、このapkをunzipすると現れるファイルの1つがclasses.dexです※3。
なお、apkには他にもAndroidManifest.xmlや、layout・drawableなどを含むresなども含まれます。
なお、multidexの場合にはこのclasses.dexが複数生成されます(classes2.dex, classes3.dexなど)。
classes.dexはJavaバイトコードをAndroidで実行できるようにしたファイル
それではclasses.dexは何なのかですが、これはJavaバイトコードをAndroidで実行できるようにしたファイルです。
Androidプロジェクトに含まれる.javaや.kotlinのファイルはjavac
やkotlinc
コマンドで**.class**というバイトコードにコンパイルされますが、この.classファイルはJVM上では実行できるものの、AndroidのランタイムであるART(旧Dalvik)では実行できません。
そこで、.classをART(旧Dalvik)で実行できるように変換したものがclasses.dexになります※4。
先ほどの図で言うと、D8というコマンドラインツール(R8じゃない)がやっているのがこのdex変換です。
なので簡単に言えば、**Java(Kotlin)ファイルをAndroid環境で実行可能な形式に変換圧縮したものがdexファイル(classes.dex)**かと思います。
ちなみに、この図にある Desuger
ですが、これはJava8などの新しい言語機能を全てのAPIレベルで使えるようにする作業です※5。
例えばJava8のラムダ機能を含むjavaファイルを.classにコンパイルし、そのclassファイルをdesugarをせずにdex変換しようとするとエラーになります。それは、Java8のラムダがminAPI26指定されているためです。これが、desugarすることによって全てのAPIレベルで使えるようなバイトコードに変換されます。
まとめ
AndroidプロジェクトにはJava(Kotlin)ファイルやAndroidManifest.xml、drawable、layuotなど様々なファイルが含まれますが、apkとして圧縮する時にはJava(Kotlin)ファイルはAndroidランタイム(ART, 旧Dalvik)で実行可能な形式に変換される必要があり、そのファイル形式がdex(Dalvik Executable)です。そして実際にapkに圧縮される時には各Javaバイトコードが1つのclasses.dexに圧縮された状態でapkに含まれます。
R8ってなんだっけ?という点については、"Shrinking Your App with R8"というYoutube動画を更にサマリーしたスライドを作成したので、そちらもご参照ください。
参考URL
※1 https://source.android.com/devices/tech/dalvik/dex-format.html
※2 https://source.android.com/devices/tech/dalvik
※3 https://developer.android.com/studio/build/apk-analyzer
※4 https://developer.android.com/studio/command-line/d8
※5 https://jakewharton.com/androids-java-8-support/#desugaring-history