#java #android-studio #event-handling #udp #runnable
#java #android-studio #обработка событий #udp #runnable
Вопрос:
Я внедрил приемник UPD в свое приложение для Android. До сих пор у меня был только один MainAvtivity, и я обновил TextView в основном пользовательском интерфейсе, передав MainActivity классу UDPReceiver.
Теперь у меня есть второе действие, и я хочу, чтобы мой UDP-приемник обновил глобальную строковую переменную, к которой затем можно получить доступ с помощью действия, которое в данный момент активно.
Также у активного действия должен быть слушатель, чтобы знать, когда появляется новое сообщение UDP. Вот код для моего UDPreceiver.
public class UDPglobalReceiver extends AppCompatActivity implements Runnable {
private final int listen2port = 12345;
private String receivedMessage;
public globalApplication application;
@Override
public void run() {
try (DatagramSocket myclientSocket = new DatagramSocket(null)) {
myclientSocket.setReuseAddress(true);
myclientSocket.setBroadcast(true);
myclientSocket.bind(new InetSocketAddress(listen2port));
while (true) {
byte[] buffer = new byte[256]; // maybe make it smaller if the messages are certainly smaller (max UDP payload)
DatagramPacket mydatagramPacket = new DatagramPacket(buffer, 0, buffer.length);
myclientSocket.receive(mydatagramPacket);
receivedMessage = new String(mydatagramPacket.getData(), "UTF8");
Log.d("UDP", "---------------- UDP: " receivedMessage);
final String[] ProcessedMessage = receivedMessage.split("\."); // Seperate by .
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
Я перезапускаю класс UDPreceiver всякий раз, когда действие изменяется:
// Start the UDP background thread
Thread myPiUDPListener = new Thread(new UDPglobalReceiver());// Create a Thread to listen UDP
myPiUDPListener.start();
Нет необходимости в фоновой активности, так что все в порядке.
Вопрос вкратце, как я могу обновить глобальную переменную в моем фоновом потоке UDPReceiver (внутри класса)? Есть ли EventListener, который прослушивает, была ли изменена глобальная переменная.
Ответ №1:
Я создал рабочее решение:
Для глобальных переменных я использовал шаблон проектирования Singleton, в котором я создал класс, который выглядит следующим образом:
import android.app.Application;
import android.util.Log;
public final class Global_Singleton extends Application {
public static volatile Global_Singleton INSTANCE = null;
private Global_Singleton() {}
// Thread safe by synchronized
// https://www.youtube.com/watch?v=vSxKnvxe8v0
public static Global_Singleton getInstance() {
if (INSTANCE == null) {
synchronized (Global_Singleton.class) {
if (INSTANCE == null) { // double check locking
INSTANCE = new Global_Singleton();
}
}
}
return INSTANCE;
}
// ---------- UDP incoming data ----------
private String[] ProcessedMessage;
public String[] getIncomingMessage() {
return ProcessedMessage;
}
public void setIncomingMessage(String[] processedMessage) {
ProcessedMessage = processedMessage;
Log.d("MINE", "---------------- Global_Singleton: " ProcessedMessage[0]);
}
}
В моем MainActivity я вызвал его, используя следующую строку:
Global_Singleton.getInstance();
С этого момента переменная может быть изменена и доступна из любого действия:
Global_Singleton.INSTANCE.setIncomingMessage(ProcessedMessage);
Чтобы реагировать на новое сообщение с сервера, я использовал общие настройки и SharedPreferences.OnSharedPreferenceChangeListener после этого видео:
https://www.youtube.com/watch?v=XEDmE-pnhqs
Я не уверен, что это лучшее решение, но оно определенно делает то, что должно делать.