Disclaimer: Это мой личный топ и субъективное мнение, материала получилось немного, но я надеюсь он будет интересным для тебя.

3 - Жестокий обман от лучшего друга от андроид студии

Знаешь ли ты такой метод как hasSystemFeature ?

Сводка из исходников
Сводка из исходников

На самом деле для того, чтобы понять этот кейс не нужно знать, что делает метод, просто представим как его вызов мог бы выглядеть в проекте:

packageManager.hasSystemFeature(PackageManager.FEATURE_NFC, 21)

Компиляция происходит успешно, по доке мы сделали все как нужно. Запускаем приложение и ловим краш.

Но почему это происходит ?

Давай теперь сходим и посмотрим документацию на сайте android.developer, а не в исходниках. Что мы тут видим ?

Метод добавлен в 24 api, а у нас 21 api. При этом в исходниках об этом нет речи. В джавадоке об этом ничего не написано. И метод не помечен аннотацией @RequiresApi, как в примере ниже:

Пример хорошего метода с аннотацией @RequiresApi
Пример хорошего метода с аннотацией @RequiresApi

Подытожим. Почему же пункт назван обман от лучшего друга ? Потому что в таких кейсах я уже как изнеженный разработчик привык, что мой добрый друг андроид студия остановит меня от подобных ошибок. Но тут не помогла ни она, ни изучение исходников. Так что всегда стоит быть настороже.

2 - Загадки startActivityForResult

Думаю ты обращал внимание, что внутри фрагмента у нас тоже есть функции startActivityForResult, а также onActivityResult. В зависимости от разных кейсов как происходит вызов startActivityForResult можно получить разное поведение. Начиная с того, что onActivityResult во фрагменте не вызовется до того, что requestCode отправляемый во фрагменте будет отличаться от того, который придет в активити. К счастью тут не нужно делать долгих описаний, так как уже есть очень крутая статья на эту тему. Но пришлось потратить немало времени когда я с этим столкнулся.

1 - История о 100 dex файлах

Знал ли ты, что если в apk твоего приложения будет больше 100 dex файлов то произойдет краш в рантайме ? Я тоже не знал, но это действительно так, однако есть маленький нюанс, такое поведение будет только на 21 api. И это была преднамеренная мера, от разработчиков из google. С 23 api краш ловить ты уже не будешь. Если интереснее почитать об этом подробнее прикладываю ссылку на статью. Но в конце той самой статьи поднимается другой вопрос. А что должно произойти, чтобы в итоговом apk появилось больше 100 dex файлов ? На самом деле тут мое расследование не зашло далеко, такое может происходить в рамках оптимизации, когда модули приложения и подключаемые библиотеки проходят фазу predexing. В результате можно обнаружить, что большое количество dex файлов просто не заполнены до конца, на скриншоте ниже это видно по их размерам:

Но было предложение написать собственную таску, которая будет склеивать эти dex файлы. Делать этого я конечно же не стал)

P.S. Напиши в комментах странности с которыми тебе пришлось столкнуться в андроиде :)

Комментарии (4)


  1. Rusrst
    04.02.2023 16:24

    Ну объективности ради startactivityforresult уже редко где и кем используется, не зря его deprecated сделали, да и контракты банально удобнее.

    Bottomsheet behavior самостоятельно обрабатывает insets...


    1. AlexWoodblock
      05.02.2023 20:10

      Вот только внутри контрактов тот же самый startActivityForResult.


      1. Rusrst
        06.02.2023 01:34

        Да, действительно, в методе onLaunch вызывается он.

        Спасибо, честно говоря до этого туда не лазил. :)


  1. Georrg
    04.02.2023 18:43
    +2

    У меня был занятный кейс: если сгенерированный модуль Даггер будет больше ~21.4 мб, вы получите ошибку сборки со ссылкой, что один из классов не добавлен)) Т.к. пилите кор на части вовремя!