Запуск приложений, содержащих большое количество кода
Фон
Кажется, что некоторые старые ОС Android (и, возможно, даже самые новые) имеют ограничение на количество кода, которое может содержать каждое приложение.
Как я обнаружил, ограничение на буфер называется LinearAlloc.
На 2.2 или 2.3 это около 5-8 МБ, и я думаю, что на других 16 или больше.
Эта проблема
Если у вас слишком большой код (и приложения могут достичь этого состояния), вы вообще не сможете установить приложение на старых устройствах, получая следующую ошибку (также сообщается здесь):
Installation error: INSTALL_FAILED_DEXOPT
Please check logcat output for more details.
Launch canceled!
Что я нашел
Одно из решений состоит в том, чтобы просто удалить как можно больше кода и библиотек, но в некоторых огромных проектах такое сделать очень сложно.
Я нашел следующие ссылки, рассказывающие о том, как Facebook решил эту проблему, увеличив лимит:
- http://www.slashgear.com/how-facebook-fixed-its-gingerbread-dalvik-problem-04272478/
- http://arstechnica.com/business/2013/03/how-facebook-dug-deep-within-android-to-fix-its-mobile-app/
- https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920
Кроме того, Google опубликовал, как решить эту проблему путем динамической загрузки кода:
http://android-developers.blogspot.co.il/2011/07/custom-class-loading-in-dalvik.html
Вопрос
Как это сделал Facebook?
Можно ли это преодолеть и другими способами?
Есть ли свободная библиотека, которая увеличивает / снимает ограничение этого буфера?
Какое ограничение на более новые версии Android, если таковые имеются?
Как другие огромные приложения (и игры) решают эту проблему? Они помещают свой код в C/C++?
Будет ли загрузка файлов dex динамически решить эту проблему?
2 ответа
Пределом является общее количество ссылок на метод:
- https://code.google.com/p/android/issues/detail?id=7147
- https://code.google.com/p/android/issues/detail?id=20814
Промежуточное место между бездействием и мультидексным подходом, описанным в статьях FB/Google, заключается в использовании такого инструмента, как ProGuard, для удаления ссылок на неиспользуемый код на уровне Java. Увидеть:
Существует новое решение от Google:
- https://plus.google.com/+IanLake/posts/JW9x4pcB1rj?utm_source=Android%20Weekly&utm_campaign=59f1f4bf4d-Android_Weekly_125&utm_medium=email&utm_term=0_4eb677ad19-59f1f4bf4d-337848877
- http://developer.android.com/reference/android/support/multidex/MultiDexApplication.html
Кажется, все, что вам нужно сделать, - это выполнить одно из следующих действий: - перейти от "MultiDexApplication" вместо "Application" - вызвать MultiDex.install(context) в attachBaseContext вашего приложения.
Но теперь мне интересно
- Это действительно так?
- Есть ли какие-либо проблемы? Влияет ли это на производительность?
- Как это работает?
- Что делать с ContentProvider, так как он вызывается до инициализации приложения?
- В посте говорится, что "вы получаете поддержку MultiDex на всех устройствах API 4+ (ну, до v21, где вы изначально это получили)" . Означает ли это, что с v21 это будет поведение по умолчанию, или просто класс будет встроен, и вам не нужно будет использовать класс библиотеки поддержки?
- Будет ли это решение работать на Eclipse?