Что такое интерфейс Runnable в Java
Что проверяют
Различаете ли вы задачу и поток. Для Android это не теория: Runnable здесь прежде всего то, что кладут в очередь обработчика сообщений, и вокруг этого крутится половина вопросов про утечки и про работу с интерфейсом.
Как отвечать
Runnable это функциональный интерфейс с единственным методом run(): без аргументов, без возвращаемого значения, без проверяемых исключений. Сам по себе он никакого потока не создаёт, это просто описание работы. Кто её выполнит, решает исполнитель: отдельный поток, пул через Executor или обработчик, привязанный к нужному циклу сообщений.
Handler main = new Handler(Looper.getMainLooper());
main.post(() -> statusView.setText(R.string.done));Стоит назвать соседа: Callable умеет вернуть результат и бросить проверяемое исключение, Runnable не умеет ни того ни другого. И различие методов: start() заводит новый поток, а прямой вызов run() просто выполняет код в текущем.
В Android применения понятные: post у представления, чтобы выполнить работу после того, как вёрстка измерена, postDelayed для отложенных действий, отдельный поток с циклом сообщений для фоновой очереди. В коде на Kotlin сверху обычно лежат корутины, но очередь под ними та же.
Где спотыкаются
Вызывают run() вместо start() и получают код в текущем потоке. Ошибка выглядит безобидно, потому что программа работает, просто вся многопоточность исчезает.
Оставляют отложенный Runnable анонимным классом внутри экрана. Нестатический класс держит ссылку на внешний объект, и до срабатывания задачи экран не освобождается. Снимать надо явно, отменой задач при уничтожении экрана.
Трогают элементы интерфейса из фоновой задачи и ловят исключение о работе не из того потока, либо наоборот выносят на главный поток сеть и диск, а потом удивляются подвисаниям при прокрутке.