Ответ
Длительные вычисления в onDraw() замедляют отрисовку UI, вызывая лаги и пропущенные кадры. onDraw() вызывается часто (при каждой перерисовке View), поэтому он должен быть максимально легковесным.
Проблемы:
- Блокировка UI-потока → ANR при долгих операциях.
- Падение FPS из-за перерисовок.
Решение:
- Выполняйте тяжелые вычисления заранее (например, в
onSizeChanged()или фоновом потоке). - Кешируйте результаты, если они не меняются.
override fun onDraw(canvas: Canvas) {
// Плохо: вычисление в onDraw
// val result = heavyCalculation()
// Хорошо: используем предвычисленное значение
canvas.drawText(cachedResult, x, y, paint)
} Ответ 18+ 🔞
А, ну это же классика, блядь! Слушай, тут такая история, как будто на дворе 2002-й год и ты пытаешься на своём кирпиче с Java ME запустить 3D-шутер. Длительные вычисления прямо в onDraw() — это пиздец какой тормозняк, ядрёна вошь!
Вот представь: твой UI-поток — это такой забеглый официант в переполненном баре. Его задача — быстро разносить пиво (onDraw()), чтобы народ не буянил (пользователь не видел лагов). А ты ему впихиваешь: «А ну-ка, братан, пока разносишь, ещё и квадратные корни в уме посчитай, и JSON распарсь, и в базу сходи». Он, конечно, ебанько, начнёт считать, а все клиенты уже волнение ебать чувствуют — стаканы стучат, FPS падает ниже плинтуса. В итоге овердохуища кадров пропущено, а самый нетерпеливый клиент (система) вызовет ANR (Application Not Responding), что-то вроде «Иди ты нахуй, официант медленный».
В чём, сука, корень зла?
- UI-поток блокируется. Он должен только рисовать, а не вычислять мировые константы. Заставишь его считать — получишь ANR, красивый диалог, после которого пользователь твоё приложение удалит.
- FPS летит в тартарары.
onDraw()зовут как сумасшедшего — на каждый чих, скролл, анимацию. Если там не легковесная отрисовка, а целая научная диссертация, то про плавность можно забыть. Будет слайд-шоу.
Как не быть распиздяем? Решения:
- Делай всё заранее, чувак! Тяжелые штуки считай где угодно, но не в самом
onDraw(). Идеальные моменты —onSizeChanged()(когда размеры известны) или, что ещё лучше, в фоновом потоке. Вычислил, сохранил в переменную, и потом только рисуешь готовый результат. - Кешируй, как последний крохобор! Если данные не меняются каждые 10 миллисекунд, зачем их пересчитывать на каждом кадре? Посчитал один раз — и используй, пока не поменяются исходники. Экономия — мать порядка.
Смотри, как это выглядит в коде:
override fun onDraw(canvas: Canvas) {
// Пиздец как плохо: вычисляем прямо здесь и сейчас.
// val result = heavyCalculation() // Тут твой UI-поток встанет колом и будет бздеть от натуги.
// А вот так — красиво и правильно: используем то, что приготовили заранее.
canvas.drawText(cachedResult, x, y, paint) // Быстро, чётко, без сюрпризов.
}
Запомни: onDraw() — это святое место для быстрой отрисовки. Не превращай его в свалку для своей вычислительной ебли. Сделаешь по-умному — интерфейс будет летать, а пользователь не захочет тебе вилкой в глаз ткнуть за тормоза. Всё гениальное просто.