如何监控LiveData hasActiveObservers()?

How to monitor LiveData hasActiveObservers()?

我有 MyRepository,它通过套接字从服务器获取实时提要。

它通过 MutableLiveData 对象向 MyViewModel 提供数据,该对象可以从片段中观察到。

为了避免浪费资源,我不希望 MyRepository 在没有观察者的情况下从服务器获取数据。

我想知道如何监控MyRepositoryMutableLiveData,所以如果没有观察者那么MyRepository 可以停止从服务器检索数据。同样,如果添加了观察者,则可以(重新)开始数据检索。

目前,我只是使用一个基本的线程(参见 createObserversMonitorThread() 方法)作为监视器:

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);
        }
    }
}

有效,但有更好的方法吗?

更新

解决方案,感谢

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.
    }
}

您可以使用 extends LiveData<T>extends MutableLiveData<T> 获取 onActive() 回调,如果您至少有 1 个活跃的观察者,您会收到通知,而 onInactive() 回调会在你从 1 个活跃观察者变成了 0 个活跃观察者。

这样你甚至不需要请求 hasActiveObservers()