2012-03-18 10 views
13

私はいくつかのアンドロイドアプリのライブラリプロジェクトを作成しています。 アプリケーションにはライブラリプロジェクトに含める共通の機能がいくつかありますが、ライブラリプロジェクト関数ではアプリケーション固有の定数を使用する必要がありますAndroid、ライブラリプロジェクトでアプリ固有の定数を提供する最も良い方法は?

私はライブラリ関数に定数の名前を付ける方法を探していますそしてこれは、それぞれに定義する必要が約60定数のほんの一例である各アプリは、彼らに

特定のアプリの定数の例を定義することができ、それはライブラリプロジェクト

public class AppConstants { 
    public static final long APP_ID = 6;//Needs to be set for each app 
} 

public static long getCurrentAppId(Context context) { 
    return getLongPreference(context, CURRENT_APP_ID_KEY, AppConstants.APP_ID); 
} 

内でどのように使用しますか多くのライブラリ関数用のapp明らかに

だから私は通常ちょうど/プロジェクト固有のapp_constants.javaファイルをインクルードインポートするだろうが、それは(当然のように)特定のアプリケーションについての手掛かりを持っていないとして、これは、ライブラリのプロジェクトファイルでは不可能である

特定のアプリごとに定数を上書きさせる最も良い方法は何ですか?

更新 は、私が(おかげで、誰も)最後に、私は、XMLソリューションを選んだ私が最も適して私のニーズに合わせて提供された見事な答えのどの決める長い時間がかかりました。それはクラッタアップ私のアプリのリソースをので、私は特にそれ好きではないと私は真剣インタフェース・ソリューションを使用することを検討しましたが、XMLソリューションが動作しないうまく

答えて

20

オプション#1 は

Context.getResources().getInteger(R.integer.app_id); 
によって

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
<item type="integer" name="app_id" format="integer">6</item> 
</resources> 

は、あなたがそれらを取得することができ、定数を定義するために各プロジェクトに

より良いオプション#2 使用のXMLリソースをごAppConstantsクラスを拡張します

各プロジェクトのリソースにxmlファイルを追加して、必要な値のみを異なる

+2

を仕事であろうとするようなものです存在する場合はアプリケーションから、そうでない場合はライブラリから削除します。つまり、アプリケーションごとに上書きしたい値のための素晴らしいアプローチです。リソースシステムを使用しているので、設定ごとに値を設定することもできます(風景とポートレートなど) – zapl

1

public enum Planet { MERCURY, VENUS, MARS } 
ように、あなたのライブラリプロジェクトに列挙のようにそれらを定義します

アンドロイド適切には別のアプローチを取り、

interface Planets { 
    static final int MERCURY = 1; 
    static final int VENUS = 2; 
    ... 
} 

、等恐ろしい定数インターフェースが、しかし、これは、周知のJavaアンチパターン(定インターフェースであり、I覆われています

定数インターフェイスパターンは、インターフェイスの使用が貧弱です。 クラスがいくつかの定数を内部的に使用することは実装の詳細です。 定数インターフェイスを実装すると、この実装の詳細が にエクスポートされ、クラスのエクスポートされたAPIにリークします。クラスのユーザが一定のインタフェースを実装することは、結果的には意味がありません。 実際には では、それらを混乱させるかもしれません。さらに悪いことに、これはコミットメントを表します。 将来のリリースでは、 が定数を使用する必要がなくなるようにクラスが変更されていますが、バイナリ互換性を確保するためにはまだインターフェイスを実装する必要があります。非最終クラスが定数 インタフェースを実装する場合、そのサブクラスはすべて、インタフェース内の定数によって汚染されたネームスペース を持ちます。列挙型の

あなたには、いくつかの理由のためにint型の値を持つように定数が必要な場合は、とのtoStringを呼び出し()が十分ではなく、あなたが列挙型を与えることができ、などの余分な情報です

public enum ZipCode { 
    LYNNWOOD(98036), SAN_JOSE(95112), ...; 

    private int zipCode; 

    private ZipCode(int zipCode) { this.zipCode = zipCode; } 

    public int getZipCode() { return zipCode; } 
} 

注意その列挙型は整数定数よりもパフォーマンスが少し劣りますが、コード構成と明快さの観点からは、はるかに優れています。

3

私はそれを行うのに最適なスキーマを知らないが、それは確かにこのように動作します:

は何かを望んでいる各アクティビティのカスタム実装してみましょう

// class, enum or whatever you want it to be. 
class BaseConstants { 
    // use some real singleton instead 
    public static final BaseConstants instance = new BaseConstants(); 

    // define those values - sadly static inheritance does not work 
    private static final int APP_ID = 0; 
    private static final int CURRENT_APP_ID_KEY = 24; 

    // so we have to do that via methods 
    protected int getAppId() { 
     return APP_ID; 
    } 
    protected int getAppIdKey() { 
     return CURRENT_APP_ID_KEY; 
    } 
} 

ライブラリ内のいくつかの基本クラスを定義します

class App1Constants extends BaseConstants { 
    public static final App1Constants instance = new App1Constants(); 

    private final static int APP_ID = 1; 

    // want a different APP_ID here. 
    protected int getAppId() { 
     return APP_ID; 
    } 

    // getAppIdKey not implemented here, uses default 
} 

は、あなたのライブラリーのための定数にコンテキストとして、そのクラスを使用することを

class Library { 
    public static long getCurrentAppId(Context context, BaseConstants settings) { 
     return getLongPreference(context, settings.getAppIdKey(), settings.getAppId()); 
    } 
} 

活動はとても

class myActivity extends Activity { 
    // each Activity can implement it's own constants class and overwrite only some values 
    private static final BaseConstants CONSTANTS = App1Constants.instance; 

    private void whatever() { 
     long appId = Library.getCurrentAppId(this, CONSTANTS); 
    } 
} 

class myActivity2 extends Activity { 
    // or could just use the default ones 
    private static final BaseConstants CONSTANTS = BaseConstants.instance; 

    private void whatever() { 
     long appId = Library.getCurrentAppId(this, CONSTANTS); 
    } 
} 

スキーマは一種の醜いですが、それはあなたのライブラリとアプリケーションで同じIDを持つリソースを定義する場合は、値を取得し、少なくとも

関連する問題