Привет, меня зовут Абакар и я работаю главным техлидом Android в Альфа-Банке.
Иногда на проекте (особенно если он большой) некоторые TODO обречены на то, чтобы остаться в нем навеки и Android Open Source Project не исключение.
Сегодня я расскажу про самые забавные тудухи из AOSP (Android Open Source Project) на которые мне приходилось натыкаться во время изучения исходников.
Disclaimer: В рамках статьи не будут открываться новые знания или подходы, просто немного фана. А также есть желание показать, что везде бывают свои проблемы — даже в больших проектах, которые делают высококлассные специалисты. И это нормально.
Когда-нибудь мы исправим тесты
Давай взглянем на кусочек кода.
Собственно, условие добавлено только для тестов и не несёт никакой функциональной полезности. TODO от начала 24-го года. Такой кейс, когда ради тестов подстраивают исходный код, выглядит как антипаттерн.
Находится в классе CarDisplayCompatScaleProviderUpdatableImpl.
К слову, ещё один пример с TODO на Javadoc — DragEvent.
Никогда не откладывайте улучшение документации на потом. Лучше сразу поправить документацию, если становится очевидно, что её тяжело понять. Иначе она не будет исправлена никогда.
Хорошо бы добавить документацию
Ещё один кусочек кода в студию!
Выглядит довольно логично. Не помешала бы дока, чтобы описать аргументы функций и ограничения с ними связанные. Тудушка была оставлена в 2013 году, и, скорее всего, пока не появилось идеи, какой должна быть эта Javadoc :)
Лежит в CommandsInterface.
Ещё пример, подтверждающий, что документацию лучше писать сразу, если есть ощущения, что она необходима. Находится он в ViewGroup.java.
Эта TODO висит уже с 2012 года. Будем надеяться, что дока появится, так как ViewGroup
не самый простой класс из Android-фреймворка ( -_•)
Как такое может происходить?
Lifecycle — как много вложено в это слово. Давайте сразу посмотрим на код.
Код находится в ActivityThread. Соответственно, этот метод дергается из TransactionExecutor. И, казалось бы, если у нас активити в started стейте и TransactionExecutor уже вызвал handleStartActivity
, то наша активити в стартед состоянии. Однако всё может поменяться прямо во время выполнения метода handleStartActivity
.
На это даже оставили замысловатую тудуху в 2019 году, но пока так и не зарезолвили. Закидывай в комменты свои идеи почему такое может происходить.
Небольшой workaround: уберём обязательно
Часто ли тебе приходилось решать проблему через workaround с надеждой, что в будущем будет применено целевое решение? Думаю, что с таким сталкивался каждый, и в большом количестве кейсов временное остается постоянным. ActivityThread не стал изменять традициям.
Думаю, нет смысла описывать в подробностях, что происходит в методе. Но этот самый workaround живёт уже с 2021 года.
Потомки точно поймут, в чём дело
Давай посмотрим на такого рода TODO, которая находится в View.java.
Видишь ли, что-то странное в коде выше ? Первое, что может попасть в глаза, так это то, что TODO абсолютно не информативно. Оно было добавлено в 2011 году, и, видимо, с того времени так и не удалось понять, что же здесь использовать.
Но есть ещё один нюанс, если присмотреться.
Внутри метода getHorizontalScrollFactor
вызывается метод getVerticalScrollFactor
. Но эту тайну забытой цивилизации нам уже раскрыть не получится. И, конечно, важный момент в том, что этот метод помечен аннотацией @UnsupportedAppUsage
.
Викторина
Думаю, ты знаешь, что у нас в Android есть UI-поток (он же MainThread). Также есть ещё RenderThread.java но в него сейчас не будем погружаться. Изменять UI нашего приложения можно только с MainThread
. Давай посмотрим на такую TODO, которая находится в ViewGroup.java.
Есть такой раздел настроек - developer options, в котором мы можем включать разнообразные настройки отладки приложения, в том числе отладку UI-компонентов. Например, Show Layout Bounds
- эта настройка показывает границы всех элементов на экране.
Так вот, внутри класса ViewGroup
есть специальные методы, которые вызываются, когда мы включаем такие опции. В том числе вызывается метод, что ты видел выше на скриншоте. И в TODO недвусмысленно говорится о том, что логика с debugLines
не будет работать с несколькими UI потоками в одном процессе.
Интересно, почему эта TODO там появилась и почему она до сих пор не решена (и скорее всего не будет решена)? Отпиши в комментах своих мысли.
Медленный hashCode
Приходилось ли тебе сталкиваться с коллекциями, которые появились вместе с Android? Например, со SparseArray? О том, почему он появился и в чём его преимущества, лучше посмотреть по ссылке в официальной доке. Но интересно, что у этой коллекции есть брат-близнец, под названием SparseRectFArray, используемый при графических вычислениях. Давай посмотрим на его метод hashCode
.
Вопрос: «Как можно улучшить эту хэш функцию?» И в чём ее недостатки сейчас? Тем не менее эти недостатки не мешают ей работать с 2014 года.
Все пользователи равны (но не всегда)
Давай заглянем в DexPathList.java, который находится в пэкедже dalvik.system
. Про Dalvik и ART можно почитать в статье Android изнутри: сравнение Dalvik и ART. Здесь у нас не совсем TODO, но тоже интересно.
Не будем погружаться в сам класс и логику его работы (если аудитории будет интересно, возможно, про это выйдет отдельная статья). Самое интересное состоит в том, что метод не удалялся только потому, что им пользовался reflection
из стороннего приложения.
Disclaimer: сейчас Dalvik не сильно актуален, так как используется ART.
А теперь погнали к итогам.
Итоги
Важно отметить, что наличие старых TODO не говорит о том, что проект плохого качества или его делали плохие инженеры.
Бывают разные кейсы, и в каких-то из них действительно оптимальнее всего бывает просто не трогать TODO. Но если ты прямо сейчас хочешь повесить какую-нибудь TODO на код, подумай несколько раз — возможно, есть смысл исправить её сразу, потому что всегда есть вероятность того, что она останется в коде навсегда. Чтобы в итоге не прийти к чему-то подобному.
И второе: если погружаешься в любой большой проект, всегда можно найти много весёлого и интересного в комментариях и TODO.
P.S. Напиши с какими забавными TODO или комментариями тебе приходилось сталкиваться в разработке.
Drake757
Хорошая статья. Я теперь знаю, что я не одинок в плане оставления странных кусков кода и более странных комментариев. Раз в исходниках Androind есть такие у себя из исправлять я конечно же не буду, а если спросят за это сошлюсь на более сильных коллег разрабов ;)