AS 2.0の新機能Instant Runについて調べた。
frameworkとは完全に無関係 :-)
- Instant Runの基本 = apkをビルドし直すこと無くアプリケーションをインストール/実行することで高速化
- apkのビルド = javaコンパイル + dex変換 + リソースのパッケージ + 転送
- これらを分解して、一部だけ行うことでapkビルドを回避する
必要な仕組み:
- dexファイルは通常は1つしかビルドされない / 1つしかロードできない
- 複数dexをロードする特殊な仕組みが必要 = (Base)DexClassLoaderの活用
- resource, assetを読み込む位置をカスタマイズ → frameworkの内部実装に手を入れる(!)
- Instant Runでは"MonkeyPatcher"
…まず、これらの仕組みを実現した、Android target側のコードが必要。
host側(IDE, コンソールツールなど、開発/デバッグ環境側)は…
- コード、リソース、アセットの部分的な更新を検出して必要な部分だけをadb pushする仕組みが必要。
- ↑の関連ファイルはapkに「含めない」ようにビルダーを構築することが必要。
- アプリケーションとして起動して、動的にコードをロードするようなスタブコードが必要。
- AS 2.0 previewをcanary channelからインストール
- 適当にプロジェクトを新規作成
- デバッグ
→ (project)/app/build/intermediaries をチェック
怪しいディレクトリがいくつか
- incremental-classes
- debug
- classes.jar - com.android.tools.fd.runtime.AppInfo.class のみ
- debug
- incremental-runtime-classes
- debug
- instant-run.jar - これがinstant runのtarget側実装
- debug
- instant-run-support
- debug
- restart-changes.txt
- debug
- Instant Run 浅析 http://jiajixin.cn/2015/11/25/instant-run/ (中文)
- AS 2.0之Instant Run的实现原理详解 (转载) http://bbs.tianya.cn/post-itinfo-396982-1.shtml (中文)
以下のプロジェクトに言及
- Nuwa, pure java implementation, can hotfix your android application: https://github.com/jasonross/Nuwa
- LayoutCase - Cast android code and resource changes to the running application through ADB: https://github.com/mmin18/LayoutCast
Instant Run全然新しくない…!!
内部にある重要そうなクラス
in com.android.build.gradle.internal.incremental:
- AndroidInstantRuntime
- IncrementalChange
- PatchesLoader
in com.android.tools.fd.runtime:
- BootstrapApplication
- IncrementalClassLoader
- MonkeyPatcher
- Restarter
- Server
AS 2.0 previewには関連するクラス名で全文検索してもコードは発見できず。
bazelに類似の仕組みを実現しているコードが含まれていた。
同ディレクトリ上の他のソースやパッケージ名からも、これらはbazel独自ではなく、com.android.tools.fd.runtimeに流用されていると推測される。
fd はたぶん fast development を表すacronym。
bazelの関連ドキュメント http://bazel.io/docs/mobile-install.html
クライアント(ホスト)側のコード: https://github.com/bazelbuild/bazel/blob/master/tools/android/incremental_install.py