如何创建“可重写的” java中的配置?

发布于 2024-11-07 16:49:38 字数 341 浏览 0 评论 0原文

我有两个基于通用代码库项目的应用程序版本。

该库使用一些常量值来确定一些运行时配置,现在我希望每个应用程序都有稍微不同的配置。

简化的问题:我的图书馆项目中有一个布尔字段,用于确定是否在我的应用程序中显示广告。默认情况下它是 true (如 Library 项目中定义的),并且应用程序版本 A 可以满足这一点。但我需要应用程序版本 B 可以免费添加,所以我需要将该值设置为 false。

如何实现这一点,以便我可以从引用该库的项目中覆盖库项目中的配置值?

我可以更改库实现和引用项目的实现。

编辑

此外,配置布尔值仅影响库代码的行为。

I have two versions of an app based on a common code library project.

The library uses some constant values to determine some runtime configurations, and now I want each app to have a slightly different configuration.

Simplified problem: I have a boolean field in my library project that determines whether or not I display ads in my app. By default it's true (as defined in the Library project), and App version A is fine with that. But I need App version B to be add free, so I need to set that value to false.

How can I implement this so that I can essentially override the configuration value in the Library project from the projects that reference the library?

I can change both the library implementation and the referencing project's implementation.

Edit

Also, the configuration boolean only affects the library code's behavior.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千鲤 2024-11-14 16:49:38

有点晚了,但我发现这个解决方案在我的项目中效果很好。它使用 Android Application 类来设置覆盖库配置的单例配置实例。

下面的ConfigConfigInstance在库中。

public final class Config {

    public static final boolean VAL;

    private Config() {}

    static {
        // this will be overridden by previous calls to 
        // ConfigInstance.getInstance()
        final ConfigInstance confInstance = ConfigInstance.getInstance(ConfigInstance.DEFAULT_VAL);
        VAL = confInstance.val;
   }

}

// Singleton helper class, be sure not to reference the Config class 
// here so that it is not loaded
public final class ConfigInstance {

    private static volatile ConfigInstance instance = null;

    static final boolean DEFAULT_VAL = false;

    public final boolean val;

    private ConfigInstance(final boolean val) {
        this.val = val;
    }

    // thread safe singleton generator
    public static ConfigInstance getInstance(final boolean val) {
        ConfigInstance result = instance;
        if (result == null) {          // 1st check no lock
            synchronized (ConfigInstance.class) {
                result = instance;
                if (result == null) {  // 2nd check with lock
                    instance = result = new ConfigInstance(val);
                }
            }
        }
        return result;
    }

}

将以下类添加到每个更高级别的项目,确保在清单中的 标记中设置“name”字段。

public class ApplicationWrapper extends Application {

    static {
        // this will set the singleton ConfigInstance first, ie. before
        // the library static block is executed; forcing it to use the 
        // values here
        ConfigInstance.getInstance(true);
   }

}

这样,项目中的 Config.VAL 将被设置为 true

A bit late, but I found that this solution works well in my projects. It uses the Android Application class to set a singleton configuration instance that overrides the config of the library.

Config and ConfigInstance below are in the library.

public final class Config {

    public static final boolean VAL;

    private Config() {}

    static {
        // this will be overridden by previous calls to 
        // ConfigInstance.getInstance()
        final ConfigInstance confInstance = ConfigInstance.getInstance(ConfigInstance.DEFAULT_VAL);
        VAL = confInstance.val;
   }

}

// Singleton helper class, be sure not to reference the Config class 
// here so that it is not loaded
public final class ConfigInstance {

    private static volatile ConfigInstance instance = null;

    static final boolean DEFAULT_VAL = false;

    public final boolean val;

    private ConfigInstance(final boolean val) {
        this.val = val;
    }

    // thread safe singleton generator
    public static ConfigInstance getInstance(final boolean val) {
        ConfigInstance result = instance;
        if (result == null) {          // 1st check no lock
            synchronized (ConfigInstance.class) {
                result = instance;
                if (result == null) {  // 2nd check with lock
                    instance = result = new ConfigInstance(val);
                }
            }
        }
        return result;
    }

}

Add the following class to each of the higher level projects, making sure to set the "name" field in the <application> tag in the manifest.

public class ApplicationWrapper extends Application {

    static {
        // this will set the singleton ConfigInstance first, ie. before
        // the library static block is executed; forcing it to use the 
        // values here
        ConfigInstance.getInstance(true);
   }

}

With this, Config.VAL will be set to true in the project.

浅浅 2024-11-14 16:49:38

只需将变量封装在 getter 函数 (getFoo()) 中并在代码中使用它即可。然后重写子类中的 getter。

Just encapsulate the variable in a getter function (getFoo()) and use it through your code. Then override the getter in your subclasses.

离不开的别离 2024-11-14 16:49:38

其他选项包括从您的上下文中获取 Android 包名称并据此做出决定,或者从清单中提取一段元数据。

Other options include getting the Android package name from your context and making a decision based on that, or pulling a piece of meta-data from your manifest.

白云不回头 2024-11-14 16:49:38

在这种情况下,您不应该使用常量值。您应该做的是创建一个带有 getter 的抽象类,然后像这样扩展该接口:

public abstract class Config {
     public abstract int getValue();
}

public class AppA extends Config {
     private static final int value = 1;

     @Override
     public int getValue(){
         return value;
     }
}

public class AppB extends Config {
     private static final int value = 2;

     @Override
     public int getValue(){
         return value;
     }
}

编辑:OP 补充说他需要库代码中的配置值。我建议仍然使用此代码,但然后在库代码中添加一个 setter,以获取应用程序设置代码中此 getter 返回的值。

You shouldn't be using a constant value in this case. What you should do is create an abstract class with a getter in it and then extend that interface like so:

public abstract class Config {
     public abstract int getValue();
}

public class AppA extends Config {
     private static final int value = 1;

     @Override
     public int getValue(){
         return value;
     }
}

public class AppB extends Config {
     private static final int value = 2;

     @Override
     public int getValue(){
         return value;
     }
}

EDIT: OP added that he needs the configuration value in his library code. I suggest still using this code, but then adding a setter in the library code to take the value returned from this getter in the application setup code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文