【问题标题】:How to handle a Remote Config instance inside a singleton如何在单例中处理远程配置实例
【发布时间】:2018-12-05 17:57:48
【问题描述】:

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

在加载启动画面时,我使用远程配置单例获取数据一次,然后,我只需访问每个类中的值,我需要该远程配置的值

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

一切正常(有时),主题在整个应用程序中都在使用这个单例进行更改,但有时在我的 SplashScreen 加载后必须返回的异步获取时间,所以我可以看到主题发生了变化我的其他活动,但不是在 SplashScreen 之后的主要活动

这是我的单身

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,直到所有的提取工作都在单例类中完成,但我也不想在第一个 Activity 上显示任何弹出对话框来告诉用户正在等待提取.

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

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

【问题讨论】:

    标签: java android firebase firebase-remote-config


    【解决方案1】:

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

    我所指的任务由此返回:

    mFirebaseRemoteConfig.fetch(0)
    

    【讨论】:

    • 谢谢Doug,试试这个!
    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-22
      • 1970-01-01
      • 2022-12-17
      • 2021-03-01
      • 2018-04-28
      • 1970-01-01
      相关资源
      最近更新 更多