Как должны взаимодействовать компоненты в многопоточном Android-приложении?
Я хочу создать простое приложение для Android, которое должно выполнять тяжелую работу в фоновом режиме. Я новичок в разработке Android и мне нужен совет, как правильно разработать это приложение.
Итак, мое приложение должно запускать сервер в фоновом режиме, который принимает клиента и постоянно взаимодействует с клиентом, пока пользователь не решит остановить сервер. У меня есть простое действие, в котором есть кнопка, которая должна запускать и останавливать сервер. Мои текущие мысли:
- Нажатие кнопки должно запустить службу
- Служба должна запускать отдельный поток, который будет выполнять всю работу сервера.
Думаю, мне нужно создать три класса:
Activity
учебный класс, Service
class (попросите систему запустить передний план Service
поэтому процесс не будет убит, если пользователь закроет Activity), а Server
класс, который может быть Thread
или AsyncTask
.Проблема заключается в том, что в потоке сервера могут происходить некоторые события, о которых должен знать пользователь, поэтому эти события должны вызывать некоторые изменения в пользовательском интерфейсе, такие как отображение сообщения. Я мог уведомить пользователя, управляя пользовательским интерфейсом в
onProgressUpdate()
метод или runOnUiThread()
но это кажется неуместным. Более того, я считаю, что это нарушает принцип единой ответственности, поскольку Сервер выполняет работу, от которой не ожидается. Может, мне стоит уведомитьService
каким-то образом, который, в свою очередь, сделает всю работу по уведомлению пользователя?Более того, мне нужно как-то управлять сервером из пользовательского интерфейса. Итак, просто позвонив
Service
и забыть об этом - не вариант.Итак, у меня вопрос: как сделать хороший дизайн приложения? Как компоненты должны взаимодействовать друг с другом?
2 ответа
Во-первых, в большинстве случаев устройство Android, выступающее в качестве сервера, является плохой конструкцией, поскольку провайдеры сотовой телефонии в настоящее время назначают своим клиентам частные IP-адреса, а не общедоступные, поэтому ваши порты прослушивания будут недоступны из Интернета. Он будет работать только в локальной сети и подключен через Wi-Fi.
Ваша серверная задача не обязательно должна быть создана в Службе, ее можно создать в других классах приложения, но вам нужно будет создать Службу, если вы хотите, чтобы поток вашего сервера не останавливался, когда телефон переходит в спящий режим, поэтому чтобы избежать этого, вам нужно будет создать службу переднего плана (службу, которая вызывает startForeground()), а также использовать PowerManager.WakeLock.
Чтобы передать задачу потоку пользовательского интерфейса, я рекомендую вам использовать сообщения, для работы в потоке пользовательского интерфейса вы создаете экземпляр производного класса Handler и перезаписываете метод handleMessage().
Из потока сервера вы можете отправлять сообщения с помощью sendMessage() производному экземпляру Handle, и вы будете получать их в handleMessage() в потоке пользовательского интерфейса.
Если вы хотите взаимодействовать с компонентом, как будто вы выполняете какую-то задачу в фоновом режиме в Службе или получаете уведомление с сервера, и вы хотите уведомить или обновить пользовательский интерфейс или все, что вы хотите здесь, в действии или фрагменте на переднем плане, например, сообщение и т. Д. тогда вы можете использовать Broadcast Receiver
Вам необходимо зарегистрировать получателя с определенным именем действия в действии или фрагменте, где вы хотите
А затем отправить широковещательную рассылку из класса обслуживания с контентом или данными с определенным именем действия через намерение
Событие запускается с действием и намерением для метода onReceive приемника широковещательной передачи, который вы объявили в действии или фрагменте, вы можете обновить пользовательский интерфейс отсюда, получив данные из намерения
Прочтите обзор трансляции из официального документа разработчика Android
https://developer.android.com/guide/components/broadcasts надеюсь, что это поможет вам