如何处理单例内部的远程配置实例

时间:2018-12-05 17:57:49

标签: java android firebase firebase-remote-config

我想做的是对Remote Config进行单例提取,以便在第一次将其加载到我的SplashScreen中。

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

我这样做是为了防止用户在活动时看到更改,这是由于我正在制作圣诞节主题,以便使用“远程配置”显示自定义布局

有时(所有)工作正常,并且主题在此单例中在整个应用程序中发生变化,但有时在加载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次启动),从我的SplashScreen内的单例获取数据是在将初始屏幕发送到第一个Activity之后获取数据,这导致我的第一个Activity没有展示主题,但我的其他“活动”展示。

我的问题是

当我在SplashScreen中时,是否仍要处理提取?

创建接口的想法会稍微减慢我的SplashScreen,直到所有的提取工作都在singleton类上完成了,但是我也不想在第一个Activity上显示任何弹出对话框来告诉用户正在等待提取

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

另外,第一次提取应该正常工作,第二次启动将加载第一次提取的数据,然后等待12h来请求新数据,因此我需要在第一次。

2 个答案:

答案 0 :(得分:1)

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

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

mFirebaseRemoteConfig.fetch(0)

答案 1 :(得分:0)

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

首先,我创建了一个接口,当提取的值为true或false时将调用

requirements.txt

然后在我的单例中,只要知道获取了接口的值,便填充该接口的值,如果发生错误,则将其设置为false

public interface SingletonListener {

    void onRemoteFetch(boolean isFetched);
}

以及该接口的实现集

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

然后在我的SplashScreen中,我只是等到获取该值后再转到仪表板,因为它是加载屏幕,所以我实际上并不关心要再等待1或2秒钟

初始化单例并附加接口

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

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

RemoteConfigSingleton.getInstance().setInterfaz(this);

由于我不在乎获取的值是true还是false,因此我在知道数据已被获取,是否已完成或发生错误之后立即访问仪表板

然后,例如,在任何需要更改主题主题的活动中,我都将其命名为christmasEvent返回的布尔值,现在我知道它具有某些值

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