dexファイルってなんだっけ

先日開催された[Android Dev Summit'19](https://developer.android.com/dev-summit)の中の["Shrinking Your App with R8"というYoutube動画](https://www.youtube.com/watch?v=uQ_yK8kRCaA)をきっかけに、Androidアプリのコード圧縮ツールであるR8について調べていたのですが、その中で出てくる**dex**について完全に忘れていたので復習しました。

## 結論

 まず結論から言うと、大雑把に表現するならば、**Java(Kotlin)ファイルをAndroid環境で実行可能な形式に変換圧縮したものがdexファイル(classes.dex)**です。

## R8とdex

そもそもR8ってなんだっけ？という点については、[上記の動画を更にサマリーしたスライド](https://speakerdeck.com/nichiyoshi/shrinking-your-app-with-r8-android-dev-summit-19-falsematome)を作成したので、そちらをご参照ください。

で、[Google Developer](https://developer.android.com/studio/releases/?hl=ja#r8-default)によると、

> R8 により、desugar、圧縮、難読化、最適化、dex 変換（D8）がすべて 1 つのステップで完了します。

<img width="758" alt="スクリーンショット 2019-11-09 0.23.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214755/640e3add-4b92-2822-f033-d70c3c9b7edc.png">

と書いてあります。

今回は、この**dex 変換**という言葉で使われている**dex**について簡単にまとめました。

## dexの由来
まず**dex**という名称なのですが、これは**Dalvik Executable**の略です※1。

「Dalvikで実行可能な」的なニュアンスかと思いますが、このDalvikというのはランタイムのことで、**Dalvikランタイムで実行可能なファイル**という意味合いだと思います。

ちなみにDalvikランタイムというのは現状のAndroidのランタイム(**Androidランタイム・ART**)の前のランタイムです※2。

## APKの中にdexが含まれている
Androidアプリをビルドした時に生成されるapk(Android Package)はzip形式のファイルなのですが、この**apkをunzipすると現れるファイルの１つがclasses.dex**です※3。
なお、apkには他にもAndroidManifest.xmlや、layout・drawableなどを含むresなども含まれます。

<img width="353" alt="スクリーンショット 2019-11-09 0.47.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214755/e0019d2e-71a2-626c-01cd-4bef1d16ed78.png">

なお、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変換**です。
<img width="758" alt="スクリーンショット 2019-11-09 0.23.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214755/640e3add-4b92-2822-f033-d70c3c9b7edc.png">

なので簡単に言えば、**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バイトコードが１つのclasses.dexに圧縮された状態でapkに含まれます。

R8ってなんだっけ？という点については、["Shrinking Your App with R8"というYoutube動画を更にサマリーしたスライド](https://speakerdeck.com/nichiyoshi/shrinking-your-app-with-r8-android-dev-summit-19-falsematome)を作成したので、そちらもご参照ください。

## 参考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