Приемник UDP в нескольких действиях с использованием Runnable: android studio

#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

Я не уверен, что это лучшее решение, но оно определенно делает то, что должно делать.