избегая статических ссылок на представления, но позволяя другим действиям изменять представления - PullRequest
0 голосов
/ 09 мая 2019

Я использую UsbSerial (com.github.felHR85: UsbSerial: 4.5) для потоковой передачи последовательных данных в мое приложение через виртуальный последовательный порт (через USB).У MainActivity есть обработчик, который обрабатывает сообщения от службы USB, аналогично представленному примеру: https://github.com/felHR85/UsbSerial/blob/master/example/src/main/java/com/felhr/serialportexample/MainActivity.java

Мое приложение имеет несколько операций, и многие из них имеют представления, которые должны измениться при определенных обстоятельствах.данные попадают через последовательный порт.Например, TextView может потребоваться обновить отображаемый текст, Button должен быть включен или отключен.

Чтобы манипулировать представлениями вне метода onCreate в каждом действии, самая простая вещьЯ пытался объявить взгляды как private static, но я видел во многих местах, что это плохая практика.Я устанавливаю ссылки View на null, как описано здесь (в разделе «2. Статические представления»), чтобы, я думаю, избежать потенциальных утечек памяти: https://blog.nimbledroid.com/2016/09/06/stop-memory-leaks.html
Мне все еще не нравится тот факт, что Lint в Android Studioуказывает «Не размещать классы контекста Android в статических полях».и что эта практика, как правило, осуждается.

Каждое действие имеет public static boolean isActive, которое устанавливается true в onResume и false в onPause

Обработчик из MainActivity решает, что делать свходящие последовательные данные в зависимости от того, какое действие выполняется в данный момент (например, SecondActivity.isActive==true).Затем он вызывает метод public static из текущего выполняемого действия (например, SecondActivity.updateViews(serialdata)), который имеет доступ к статической ссылке на представление для выполнения того, что ему нужно (например, myTextView.setText(serialdata))

Если я не должен '• Сохраняйте статическую ссылку на представление. Каковы альтернативы достижению того, что мне нужно, т.е. обновления элемента представления в SecondActivity из обработчика в MainActivity, в то время как SecondActivity уже запущен?

1 Ответ

1 голос
/ 09 мая 2019

У MainActivity есть обработчик, который обрабатывает сообщения от службы USB

Это плохой план.

В моем приложении несколькоДействия, и многие из них имеют представления, которые должны измениться, если определенные данные попадают через последовательный порт.

Это показывает, почему плохой план не является хорошим.Данные, поступающие из последовательного порта, не привязаны исключительно к MainActivity ... так почему бы MainActivity обрабатывать служебные сообщения USB?

(также вполне вероятно, что вам не нужно выполнять несколько действийздесь и вместо этого есть одно действие с несколькими фрагментами, но я пока оставлю это в стороне)

Какие есть альтернативы для достижения того, что мне нужно

Я незнать, что находится на другом конце последовательного порта, который вызывает отправку сообщений.Для целей этого ответа я назову его «штуковиной».

Шаг # 1: Создайте ThingyRepository.Это будет класс (с единичным экземпляром), который управляет последовательным соединением USB и принимает сообщения.Он будет удерживать некоторое представление текущего состояния на основе прошлых сообщений (ThingyState) и обновит это состояние по мере поступления новых сообщений.

Шаг # 2: ThingyRepository выставить какое-то "реактивный API ".Это может быть что-то современное, например, LiveData или RxJava.Это может быть что-то более старое, например, основанный на обратном вызове API.В любом случае вы хотите, чтобы ThingyRepository доставлял обновленные ThingyState объекты заинтересованным сторонам («наблюдателям») при изменении состояния.Итак, ThingyRepository преобразует последовательные сообщения USB в обновленные состояния и при необходимости выдает эти состояния.

Шаг № 3: ваш пользовательский интерфейс наблюдает ThingyRepository, получает объекты ThingyState и обновляет пользовательский интерфейсна основании этих состояний.В идеале вы должны использовать ViewModel для передачи данных, для изменения конфигурации Android (поворот экрана и т. Д.).Но, если вы хотите остаться "старой школой", действие может зарегистрировать обратный вызов с вашим ThingyRepository, где ThingyRepository может вызвать обратный вызов с новым ThingyState, поскольку данные изменяются в зависимости от сообщений USB.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...