2011-05-17 102 views
0

我有一個基於通用代碼庫項目的應用程序的兩個版本。如何在java中創建一個「可覆蓋」的配置?

該庫使用一些常量值來確定某些運行時配置,現在我希望每個應用程序具有稍微不同的配置。

簡化問題:我的庫項目中有一個布爾字段,用於確定是否在我的應用中顯示廣告。默認情況下它是真實的(正如在庫項目中定義的那樣),而App版本A也可以。但我需要App版本B免費添加,所以我需要將該值設置爲false。

我該如何實現這個功能,以便我可以從引用庫的項目中覆蓋庫項目中的配置值?

我可以改變庫實現和引用項目的實現。

編輯

此外,配置布爾隻影響庫代碼的行爲。

+0

您可以私有化布爾引用並添加一個公共方法,根據需要返回true/false。應用程序版本B可以覆蓋以返回false。 – Swati 2011-05-17 20:37:02

+2

如果它不是常量,不要稱之爲常量。這聽起來更像一個配置(有很多方法來創建/使用配置)。 – 2011-05-17 20:39:15

+0

@Swati,我想到了,但它是需要布爾值的庫代碼,所以它永遠不會看到覆蓋。 – CodeFusionMobile 2011-05-17 20:41:52

回答

1

只需將變量封裝在getter函數(getFoo())中並通過代碼使用它即可。然後重寫你的子類中的getter。

+0

我想到了這一點,但庫代碼需要配置變量,而不是版本特定的代碼。圖書館將不知道新的子類 – CodeFusionMobile 2011-05-17 20:43:10

+0

哦,不知道當我寫我的答案。在這種情況下,您需要實現我的答案,然後通過函數參數將值傳遞迴庫中。 – 2011-05-17 20:47:50

0

在這種情況下,您不應該使用常數值。你應該做的是創建一個抽象類中有一個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返回的值。

+0

如果AppA代碼和AppB代碼需要不同的值,則這是正確的方法。但是我需要現有庫代碼的值以庫代碼可見的方式進行更改。 – CodeFusionMobile 2011-05-17 20:51:27

+0

看看我的編輯在底部。 – 2011-05-17 20:54:17

1

其他選項包括從您的上下文中獲取Android包名稱並根據此名稱作出決定,或從清單中提取一段元數據。

+0

+1不回答我的直接問題,但可能是我最終會做的 – CodeFusionMobile 2011-05-17 21:23:49

2

有點晚了,但我發現這個解決方案在我的項目中效果很好。它使用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; 
    } 

} 

添加下面的類的每個上級項目,確保設置在清單中的<application>標籤中的「名稱」字段。

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