如何在单例中处理远程配置实例

How to handle a Remote Config instance inside a singleton

我想做的是制作一个远程配置获取的单例,以便在我的 SplashScreen 中第一次加载它。

当我的闪屏正在加载时,我使用我的远程配置单例获取数据一次,然后,我只访问每个 class 中的值,我需要该远程配置的值

我这样做是为了防止用户在 Activity 上看到更改,这是因为我正在制作圣诞主题,以便显示带有远程配置的自定义布局

一切正常(有时)并且主题在整个应用程序中随着这个单例发生变化,但有时在我的 SplashScreen 加载后异步获取时间必须花费 returns,所以我在 SplashScreen

之后可以看到主题在我的其余 Activity 中发生了变化,但在主 Activity 中却没有

这是我的单身狗

public class PruebaSingleton {

    private boolean christmasEvent;
    private FirebaseRemoteConfig mFirebaseRemoteConfig;
    private static volatile PruebaSingleton _instance;

 private PruebaSingleton(){
        fetchRemoteConfig();
    }

    public synchronized static PruebaSingleton getInstance(){
        if(_instance == null){

            synchronized (PruebaSingleton.class) {
                if (_instance == null) _instance = new PruebaSingleton();
            }
        }

        return  _instance;
    }

    private void fetchRemoteConfig() {
        mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance();
        mFirebaseRemoteConfig.setConfigSettings(
                new FirebaseRemoteConfigSettings.Builder().setDeveloperModeEnabled(BuildConfig.DEBUG)
                        .build());

        mFirebaseRemoteConfig.fetch(0).addOnCompleteListener(task -> {
            if (task.isSuccessful()) {

                 mFirebaseRemoteConfig.activateFetched();

            }

            christmasEvent = mFirebaseRemoteConfig.getBoolean("christmas_ottaa_mode");

        }).addOnFailureListener(e -> {

        });
    }
    public boolean isChristmasModeEnabled(){
        return christmasEvent;
    }

现在,在此之后,我只实例化一次此单例以获取远程配置的数据并影响我的整个应用程序。

在我的SplashScreen onCreate()

PruebaSingleton.getInstance();

然后我就通过这种方式在我的所有活动中获取布尔值

PruebaSingleton.getInstance().isChristmasModeEnabled();

然后,我可以更改主题。

问题是有时(不常见,但在大约 10 次启动中发生了 2 次)在启动画面发送到第一个 Activity 后,从我的 SplashScreen 中的单例获取数据,这导致我的第一个 Activity 没有显示主题,但我的其他活动显示了主题。

我的问题是

当我在我的 SplashScreen 中时,是否有任何方式来处理提取?

考虑创建一个界面会使我的 SplashScreen 变慢一点,直到所有的获取工作都在单例中完成 class,但我也不想在第一个显示任何弹出对话框 Activity 告诉用户正在等待获取。

这更像是一个性能问题,因为当提取完成时,启动画面需要快速转到第一个 activity 而不是等待更多时间来获取数据,因为如果发生这种情况我会减少尝试加载圣诞主题的应用程序性能。

而且第一次获取应该正常工作,第二次启动将加载第一次获取的数据,然后等待 12 小时请求新数据,所以我需要让所有具有获取值的活动第一次是真的。

您的单身人士需要公开一种方法,让其他代码附加一个侦听器以了解提取何时完成,类似于您将侦听器附加到执行提取的任务的方式。或者您可以只公开任务本身。

我指的任务是这样返回的:

mFirebaseRemoteConfig.fetch(0)

正如 Doug 所说,我已经通过一个简单的回调解决了这个问题,这是我所做的以及它是如何工作的。

首先,我创建了一个接口,该接口将在完成提取的值 true 或 false 时调用:

public interface SingletonListener {

    void onRemoteFetch(boolean isFetched);
}

然后在我的单例中,当我知道它被获取时,我只填充接口的值,如果发生错误,我只是将它设置为 false:

 mFirebaseRemoteConfig.fetch(0).addOnCompleteListener(task -> {
            if (task.isSuccessful()) {

                mFirebaseRemoteConfig.activateFetched();

            }

            christmasEvent = mFirebaseRemoteConfig.getBoolean("christmas_ottaa_mode");
            mSingletonListener.onRemoteFetch(christmasEvent);
        }).addOnFailureListener(e -> {

            mSingletonListener.onRemoteFetch(false);

        });



   //Setters and getters, so in Splash, when I know it's fetched I just set the value to the Singleton and then just get it everywhere in the app
   
 public boolean isChristmasMode() {
            return christmasMode;
        }
    
        public void setChristmasMode(boolean christmasMode) {
            this.christmasMode = christmasMode;
        }

以及该接口的实现集合:

public void setInterfaz(SingletonListener listener){
        this.mSingletonListener = listener;
    }

然后在我的 SplashScreen 中,我只是等到该值被提取到仪表板,因为它是一个加载屏幕,我真的不在乎多等 1 或 2 秒:

初始化单例并附加接口

RemoteConfigSingleton.getInstance().setInterfaz(this);

然后实现该方法并等待结果访问仪表板:

 @Override
    public void onRemoteFetch(boolean isFetched) {
        accessDashboard();
        RemoteConfigSingleton.getInstance().setChristmasMode(isFetched);
    }

由于我不关心获取的值,无论是真还是假,我在知道数据已被获取后访问仪表板,如果它已完成或发生错误。

然后例如在任何 Activity 中我需要更改主题的东西我只是调用 christmasEvent 返回的布尔值,现在我知道它有一些值:

        if(RemoteConfigSingleton.getInstance().isChristmasMode()){
            toolbar.setBackgroundResource(R.color.christmas);
            Christmas stuff...
        }
    }