Я думаю, что главное понять, что в потоке пользовательского интерфейса должны выполняться только задачи, специфичные для пользовательского интерфейса.Если это не связано с пользовательским интерфейсом, то он должен работать в другом потоке, в идеале как AsyncTask.
Выполнение поиска, вообще говоря, очень сильно влияет на производительность, как вы указали.Это заблокирует поток пользовательского интерфейса от обновления пользовательского интерфейса, что приведет к не отвечающим пользовательским интерфейсам, и пользователи могут воспринимать это как сбой или медленное приложение.
Итак, во-первых, чтобы запустить обновление в потоке пользовательского интерфейса.
runOnUiThread(() ->{textView.setText("loading...");});
, затем выполните поиск в другом потоке
, затем, как только поиск завершится, обновите пользовательский интерфейс, используя тот же метод, что и выше