Есть ли лучший способ периодически обновлять пользовательский интерфейс

#java #android #multithreading #performance #android-handler

#java #Android #многопоточность #Производительность #android-обработчик

Вопрос:

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

Я попытался создать Handler объект и вызвать postDelayed(Runnable r, long delayMillis) , и он работает так, как ожидалось:

Инициализация Handler и Runnable

 
private static final int SOME_INTERVAL = 10000;
private Handler mHandler = new Handler();

private Runnable mPrinterUpdaterRunnable = new Runnable() {
        @Override
        public void run() {
            updatePrinterIndicator(); \ do some stuff
            mHandler.postDelayed(this, SOME_INTERVAL);
        }
    };

private void updatePrinterIndicator() {
        // check printer status and update some view for instance ImageView
    }
  

После этого мне нужно запускать Handler при запуске activity и удалять все обратные вызовы, когда пользователь покидает activity, поэтому я пишу:

 @Override
public void onResume() {
    super.onResume();
    mHandler.postDelayed(mPrinterUpdaterRunnable , 0);
}

@Override
public void onPause() {
    mHandler.removeCallbacksAndMessages(null);
    super.onPause();
}
  

Итак, если я правильно понимаю, весь код в run() методе mPrinterUpdaterRunnable будет выполняться в основном потоке пользовательского интерфейса.

Есть ли лучший способ сделать это или я уже использую лучший способ сделать это? Не выполнять весь код в основном потоке пользовательского интерфейса и только для примера someView.setImageResource(someID)

Ответ №1:

Вы можете запускать свой код в фоновом потоке, используя как минимум 3 из этих параметров:

  1. Использование RxJava;
  2. Используя пользовательский класс, подобный этому;
  3. Если вы используете Kotlin, тогда сопрограммы;

Есть и другие способы сделать это. RxJava обладает большим потенциалом в долгосрочной перспективе, если вы намерены значительно расширить свой проект. Кроме того, это имеет гораздо более крутую кривую обучения.

Второе решение отлично подходит для проектов малого и среднего размера и является самым простым вместе с сопрограммами.

После добавления класса AppExecutors (2-е решение) вы бы использовали его следующим образом:

 new AppExecutor().diskIO().execute(new Runnable() {
        @Override
        public void run() {
            // Do your stuff
        }
    });
  

Дайте мне знать, если я смогу помочь!