Я хочу немного изменить исходный код Android, чтобы он соответствовал моим требованиям.Вот требование:
Я хочу проиндексировать все объекты в приложении для Android, добавив еще одно открытое поле int
в класс java.lang.Object
.Следовательно, все классы могут наследовать добавленное поле, поскольку все они являются подклассами класса Object
.
На данный момент я изменил класс java.lang.Object
в папке <Android_source>/libcore/libart/src/main/java/java/lang
и перекомпилировал исходный код.
Я хочу спросить, правильно ли я поступаю.Может ли мое приложение для Android распознать это изменение (например, может ли объект String
получить доступ к недавно добавленному полю)?
Редактировать
Примерно через 3 недели попыток и ошибок я наконец получил полный ответ.Я хочу поделиться этим опытом с другими, если кто-то еще хочет изменить основные библиотеки Java исходного кода Android (например, изменить Object.java
и String.java
и т. Д.).Опять же, как упомянул Майкл, обратите внимание, что такая модификация может быть пригодна только для целей исследования или тестирования.
Ключевая проблема в создании успешной модификации (здесь «успешная» означает, что модифицированный исходный код Android может быть создани запускаться на эмуляторах или реальных устройствах без каких-либо проблем) заключается в том, что некоторые классы в базовой библиотеке Java имеют свои зеркала C ++ (расположены в <Android_source>/art/runtime/mirrors/
).При изменении этих классов Java вы должны также сделать те же самые модификации для их зеркал C ++.В противном случае вы можете потерпеть неудачу в процессе сборки, потому что вам нужно пройти кучу проверок.Поскольку я добавляю только новое поле в Object.java
, я перечислю некоторые проверки (или требования), с которыми я столкнулся ниже:
1. Размер экземпляра объекта = размер его зеркала C ++.Например, если я добавлю поле long
в Object.java
, я также должен добавить поле uint64_t
к его зеркалу C ++, чтобы сделать их размер равным.
2. Попробуйте сделать размерЭкземпляр объекта должен быть степенью 2 (например, 2, 4, 8, 16, ...).Например, размер исходного Object.java
равен 8, поэтому я добавляю длинное поле, чтобы увеличить размер до 16. Если я добавлю поле int, размер станет 12, и он может не пройти много проверок.Я не понимаю точную причину, но я предполагаю, что это как-то связано с выравниванием памяти .
3. Попытайтесь поместить поля примитивного типа после полей не примитивного типа иполя примитивного типа должны быть упорядочены по размеру.Это означает, что вы должны поместить поля ссылочного типа впереди, затем поля 8-байтового типа, затем поля 4-байтового типа, затем поля 2-байтового типа, затем 1-байтовый элементполя типа.Опять же, я думаю, причина в выравнивании памяти
Это все, что я сделал, чтобы удовлетворить свои требования.Я открыт для любых обсуждений, если у вас есть какие-либо идеи относительно цели этих проверок (особенно 2-й и 3-й)