Saya memiliki MyRepository yang memperoleh umpan langsung dari server melalui soket.

Ini memberikan datanya ke MyViewModel melalui objek MutableLiveData yang dapat diamati dari Fragmen.

Untuk menghindari pemborosan sumber daya, saya tidak ingin MyRepository memperoleh data dari server saat tidak ada pengamat.

Saya ingin tahu cara memantau MyRepository MutableLiveData, jadi jika tidak ada pengamat maka MyRepository dapat berhenti mengambil data dari server . Demikian pula, jika seorang pengamat ditambahkan, maka pengambilan data dapat (kembali) dimulai.

Saat ini, saya hanya menggunakan Thread dasar (lihat metode createObserversMonitorThread()) sebagai monitor:

public class MyRepository {

    private static final String TAG = MyRepository.class.getSimpleName();

    private MutableLiveData<String> mutableLiveData;
    
    private Socket mSocket = null;

    public MyRepository(Application application) {

        mutableLiveData = new MutableLiveData<>();

        createSocket();
        
        createObserversMonitorThread();
    }

    private void createObserversMonitorThread() {

        Thread thread = new Thread() {

            @Override
            public void run() {

                try {
                    while (isAlive()) {

                        if (mutableLiveData.hasActiveObservers()) {

                            // We have observers, so connect to the server.
                            if (!mSocket.connected()) {
                                mSocket.connect();
                            }
                        }
                        else {

                            // We don't have observers, so disconnect from the server.
                            if (mSocket.connected()) {
                                mSocket.disconnect();
                            }
                        }

                        // Wait until next loop.
                        Thread.sleep(1000);
                    }
                }
                catch(Exception e) {

                    Log.e(TAG, "Exception", e);
                }
            }
        };

        thread.setName("MutableLiveData Observers Monitor");
        thread.setPriority(1);
        thread.setDaemon(true);
        thread.start();
    }

    public LiveData<String> getMutableLiveData() {
        return mutableLiveData;
    }

    /**
     * This method posts retrieved data to mutableLiveData.
     */
    private void createSocket() {

        try {
            mSocket = IO.socket(Constants.SERVER_URL);
            mSocket.on(Socket.EVENT_CONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    Log.d(TAG, "Connected.");
                }
            }).on(Socket.EVENT_CONNECT_ERROR, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    if (args[0] instanceof Exception) {
                        Log.e(TAG, "Connect error: ", (Exception)args[0]);
                    }
                    else {
                        Log.e(TAG, "Connect error: " + args[0]);
                    }
                }

            }).on(Socket.EVENT_RECONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    Log.d(TAG, "Reconnected.");
                }
            }).on(Socket.EVENT_RECONNECT_ERROR, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    if (args[0] instanceof Exception) {
                        Log.e(TAG, "Reconnect error: ", (Exception)args[0]);
                    }
                    else {
                        Log.e(TAG, "Reconnect error: " + args[0]);
                    }
                }

            }).on(Socket.EVENT_MESSAGE, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    //Log.d(TAG, "Data received.");

                    String s = (String) args[0];
                    mutableLiveData.postValue(s);
                }

            }).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {

                @Override
                public void call(Object... args) {
                    Log.d(TAG, "Disconnected.");
                }

            }).on(Socket.EVENT_ERROR, new Emitter.Listener() {

                @Override
                public void call(Object... args) {

                    if (args[0] instanceof Exception) {
                        Log.e(TAG, "Error: ", (Exception)args[0]);
                    }
                    else {
                        Log.e(TAG, "Error: " + args[0]);
                    }
                }

            });
        }
        catch(Exception e) {
            Log.e(TAG, "Could not create socket", e);
        }
    }
}

Ini berhasil, tetapi apakah ada cara yang lebih baik?

PERBARUI

Solusi, berkat jawaban EpicPandaForce:

public class MyRepository {

    private static final String TAG = MyRepository.class.getSimpleName();

    private MutableLiveData<String> mutableLiveData;

    private Socket mSocket = null;

    public MyRepository(Application application) {

        createSocket();

        mutableLiveData = new MutableLiveData<String>() {

            @Override
            protected void onActive() {
                super.onActive();

                // Connect to server. This will (re)start data being posted on mutableLiveData.
                if (!mSocket.connected()) {
                    mSocket.connect();
                }
            }

            @Override
            protected void onInactive() {
                super.onInactive();

                // Disconnect from server. This will stop data being posted on mutableLiveData.
                if (mSocket.connected()) {
                    mSocket.disconnect();
                }
            }
        };
    }

    public LiveData<String> getMutableLiveData() {
        return mutableLiveData;
    }

    /**
     * This method posts retrieved data to mutableLiveData.
     */
    private void createSocket() {
        // Same code as before.
    }
}
2
ban-geoengineering 1 Juli 2020, 13:38

1 menjawab

Jawaban Terbaik

Anda dapat menggunakan extends LiveData<T> atau extends MutableLiveData<T> untuk mendapatkan panggilan balik onActive() di mana Anda akan diberi tahu jika Anda memiliki setidaknya 1 pengamat aktif, dan onInactive() panggilan balik saat Anda beralih dari 1 ke 0 pengamat aktif.

Dengan begitu Anda bahkan tidak perlu meminta hasActiveObservers().

3
EpicPandaForce 2 Juli 2020, 03:50