динамическая загрузка Dex файла в Dalvik
Dec. 15th, 2010 02:49 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
В общем и с явовской виртуальной машиной вышло по сценарию -- "хотели как лучше, а получилось -- как всегда." ;-) Вроде бы делали универсальный байткод, который write once, run anywhere... Сделали. Но теперь неймется компании Google, которая мало того, что написала для Явы новую виртуальную машину, да еще к тому-же и совершенно другой архитектуры.
Большинству, конечно, все равно, они свои программы перекомпилируют специальным гуглевским компилятором (который из обычных Java class files делает Dalvik-овские dex файлы). А что делать нам, несчастным писателям компиляторов ? ;-)
Но мало того, то байткод другой архитектуры. Еще и загружать динамически его приходится по-новому. И не просто по-новому, оказывается сам этот байткод Dalvik загрузить непосредственно не может, только из zip архива... В общем, грабли на граблях.
Ну вот я вроде разобрался. Пишу, чтобы зафиксировать. Вам это, скорее всего, будет не интересно. ;-)
Итак, возьмем программу Hello.java с одним единственным методом hello, который очевидно что делает. Задача в том, чтобы загрузить этот файл в Андроид динамически, непосредственно в двоичном виде.
Тоесть загрузить нужно Вот этот zip файл, созданный командой:
Ну не жуть ли ? ;-)
Так что, наступает эра многоплатформенных компиляторов в явовские байткоды со всеми вытекающими "прелестями". Да, явовский байткод не очень оптимален в плане используемого пространства, но неужели такая оптимизация, всего-лишь в несколько раз, стоила того ? И все равно-ж, гады, в процессе загрузки этого .zip с файлом .dex (вызов конструктора DexFile), они докомпилируют его в "оптимизированный" байткод в формате .odex, который еще хранят в отдельном файле.
Вот такая вот бессмысленная политика (ибо по-другому мне это сложно объяснить). Нет, для меня это, конечно, выгодно. Я то думал проект уже закончен. А тут опа, появляется возможность переписать все заново (с сохранением старого, проверенного и удобного API). Типа раз, и снова в девках. ;-) Хорошо, но бессмысленно.
По-хорошему нужно было спрятать свой dalvik подальше (как implementation detail, раз уж они верят, что именно такой подход даст им performance edge), включить в стандартную поставку перекомпилятор dx в прозрачном режиме и пройти явовский testsuite.
Большинству, конечно, все равно, они свои программы перекомпилируют специальным гуглевским компилятором (который из обычных Java class files делает Dalvik-овские dex файлы). А что делать нам, несчастным писателям компиляторов ? ;-)
Но мало того, то байткод другой архитектуры. Еще и загружать динамически его приходится по-новому. И не просто по-новому, оказывается сам этот байткод Dalvik загрузить непосредственно не может, только из zip архива... В общем, грабли на граблях.
Ну вот я вроде разобрался. Пишу, чтобы зафиксировать. Вам это, скорее всего, будет не интересно. ;-)
Итак, возьмем программу Hello.java с одним единственным методом hello, который очевидно что делает. Задача в том, чтобы загрузить этот файл в Андроид динамически, непосредственно в двоичном виде.
Тоесть загрузить нужно Вот этот zip файл, созданный командой:
javac Hello.java && \ dx --dex --output=Hello.zip Hello.class && \ adb -e push Hello.zip /data/localЧтобы это сделать, нужна вот такая программа SayHello.java, которая компилируется и работает вот так:
javac SayHello.java && \ dx --dex --output=SayHello.zip SayHello.class && \ adb -e push SayHello.zip /data/local \ adb -e shell dalvikvm -classpath /data/local/SayHello.zip SayHello Note: SayHello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details. 43 KB/s (2034 bytes in 0.045s) Hi ! Im' your "Hello World" loader ! First, I'm hooking the DexFile class...Good. Second, I'm getting hold of its constructor...Good. Third, I'm instantiating the DexFile object on "/data/local/Hello.zip"...Good. Fourth, I'm getting to its loadClass method...Good. Fifth, loading Hello class from the loaded dex...Good. Sixth, getting hello method of Hello class...Good. Seventh, invoking the hello method: Hello WORLD ! Done. Easy, isn't it ? ;-)
Ну не жуть ли ? ;-)
Так что, наступает эра многоплатформенных компиляторов в явовские байткоды со всеми вытекающими "прелестями". Да, явовский байткод не очень оптимален в плане используемого пространства, но неужели такая оптимизация, всего-лишь в несколько раз, стоила того ? И все равно-ж, гады, в процессе загрузки этого .zip с файлом .dex (вызов конструктора DexFile), они докомпилируют его в "оптимизированный" байткод в формате .odex, который еще хранят в отдельном файле.
Вот такая вот бессмысленная политика (ибо по-другому мне это сложно объяснить). Нет, для меня это, конечно, выгодно. Я то думал проект уже закончен. А тут опа, появляется возможность переписать все заново (с сохранением старого, проверенного и удобного API). Типа раз, и снова в девках. ;-) Хорошо, но бессмысленно.
По-хорошему нужно было спрятать свой dalvik подальше (как implementation detail, раз уж они верят, что именно такой подход даст им performance edge), включить в стандартную поставку перекомпилятор dx в прозрачном режиме и пройти явовский testsuite.
no subject
Date: 2010-12-15 08:11 pm (UTC)PathClassLoader, а так-же DexClassLoader -- это такое западло для "умников", которые вооружившись тем-же ха-ха Гуглем, думают, что они могут теперь легко беседовать на равных на любые темы от кодогенераторов, до адронного коллайдера. Загрузку непосредственно из raw dex ни PathClassLoader, ни DexClassLoader на сегодня не поддерживает. Да, там написано, что поддерживает, я знаю. Но, если на заборе написано Х.., это-же не значит, что там действительно ... ;-))
Нет, ну Вы попробуйте, конечно... ;-)))
К.Л.М.