0

私の Android アプリケーションでは、アプリケーションのさまざまなアクティビティで必要なユーティリティ関数で構成されるクラスを作成しました。このクラスでは、(ファイルを操作するための) コンテキスト変数と、設定マネージャーと設定エディターのインスタンスが必要です。また、タイムスタンプとして現在の日付を表す long integer が必要です。

private static long today;
private static Context myContext;
private static SharedPreferences sharedPrefs;
private static Editor editor;

これらの変数を初期化する正しい方法はどれですか。以下に示すように、プライベートコンストラクターを介して実行しようとしましたが、エラーが発生しています。

private NetworkController()
{
    //Getting the Unix timestamp for today
    GregorianCalendar aDate = new GregorianCalendar();
    GregorianCalendar tDate = new  
    GregorianCalendar(aDate.get(Calendar.YEAR),aDate.get(Calendar.MONTH),  
    aDate.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
    today = (tDate.getTimeInMillis())/1000; 
     //The preferences manager for reading in the preferences
    sharedPrefs = PreferenceManager.getDefaultSharedPreferences(myContext);
    //The preferences editor for modifying the preferences values
    editor = sharedPrefs.edit();
}

1 つのアプローチは、使用されるすべてのアクティビティでこのクラスのインスタンスを作成することですが、私はそれをしたくありません。他のアプローチは可能ですか?

4

4 に答える 4

1

どこでも使用するもののセットがあり、インスタンスが 1 つだけ必要な場合は、singletonと呼ばれるものを使用できます。たとえば、これは という整数を保持する非常に単純なものですlevel

public class Utility {
    private static Utility theInstance;

    public int level;

    private Utility() {
        level = 1;
    }

    public static getUtility() {
        if (theInstance == null) {
            theInstance = new Utility();
        }
        return theInstance;
    }

}

次に、これを次のように使用できます。

Utility u = Utility.getUtility();
u.level++;

ただし、シングルトンはプログラムの動作を混乱させる可能性があるため、多くの人がシングルトンの使用を思いとどまらせます。このトピックに関する良い記事はSingletons are Pathological Liarsです。シングルトンは状況によっては便利ですが、シングルトンを使用する際の落とし穴に注意する必要があります。

于 2012-05-21T22:10:55.553 に答える
0

ここにはすでにたくさんの良い提案が投稿されていますが、この種の「ユーティリティ」/「ヘルパー」関数の別のアプローチは、ロジックが機能するために必要なパラメーターを単純に渡すことだと思います。あなたの場合、ローカル参照でロジックを機能させる代わりに、次のContextように渡すことができます。

public static void NetworkController(Context context) {
    //Getting the Unix timestamp for today
    GregorianCalendar aDate = new GregorianCalendar();
    GregorianCalendar tDate = new  
    GregorianCalendar(aDate.get(Calendar.YEAR),aDate.get(Calendar.MONTH),  
    aDate.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
    long today = (tDate.getTimeInMillis())/1000; 
    //The preferences editor for modifying the preferences values
    SharedPreferences.Editor editor = PreferenceManager.getDefaultSharedPreferences(context).edit();
    ...
}

その場で計算/推定できる他の変数。おそらくもう少しガベージコレクションを意味しますが、メモリ管理の観点からは比較的安全なはずです。

于 2012-05-22T00:09:19.050 に答える
0

ここでこれを行うことができます:

public class NetworkController {

     SharedPreferences settings;
     SharedPreferences.Editor editor;


     public NetworkController(Context context){
        settings = PreferenceManager.getDefaultSharedPreferences(context);
        editor = settings.edit();
     }

     public void saveName(String name){
          editor.putString("name", name).commit();
     }

     public String getName(){
          return settings.getString("name");
     }

     public static long getTimeStamp(){
          return System.currentTimeMillis();
     } 

}

以下のようなクラスを使用できます。

 NetworkController prefs = new NetworkController(context); // Context being an Activity or Application
 prefs.saveName("blundell");
 System.out.println(prefs.getName()); // Prints 'blundell';
 System.out.println(NetworkController.getTimeStamp()); // Prints 1294931209000

すべてのクラスでインスタンスを作成したくない場合は、アプリケーションのインスタンスで作成し、常にそれを参照できます。

public class MyApplication extends Application {

     private NetworkController myPrefs;

     public NetworkController getPrefs(){
          if(myPrefs == null){ // This is called lazy initialization
             myPrefs = new NetworkController(this); // This uses the Application as the context, so you don't have issues when Activitys are closed or destroyed
          }
          return myPrefs;
     }

}

MyApplicationをマニフェストに追加する必要があります。

<application 
    android:name="com.your.package.MyApplication"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name">

この単一のインスタンスを使用するには、次のようにします。

public class MyActivity extends Activity {


     public void onCreate(Bundle savedInstanceState){
          super(savedInstanceState);

          NetworkController prefs = ((NetworkController) getApplicationContext()).getPrefs();

          // use this object just like shown above
          prefs.saveName("blundell"); // etc
     }

}
于 2012-05-21T22:17:20.760 に答える
0

@Gregは正しいです。やりたいことに静的なものを使用しないでください。ここに通常のオブジェクトを置きたくない理由はありません。コンテキストをパラメーターとして渡し、必要なときにオブジェクトをインスタンス化します。

private long today;
private Context myContext;
private SharedPreferences sharedPrefs;
private Editor editor;

public NetworkController( Context context )
{
    this.context = context;
    //Getting the Unix timestamp for today
    GregorianCalendar aDate = new GregorianCalendar();
    GregorianCalendar tDate = new  
    GregorianCalendar(aDate.get(Calendar.YEAR),aDate.get(Calendar.MONTH),  
    aDate.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
    today = (tDate.getTimeInMillis())/1000; 
     //The preferences manager for reading in the preferences
    sharedPrefs = PreferenceManager.getDefaultSharedPreferences(this.context);
    //The preferences editor for modifying the preferences values
    editor = sharedPrefs.edit();
}

シングルトンはプログラミングの悪い方法であり、テストが非常に難しくなります。まだテストを使用していなくても、シングルトンを使用しないでください。物事がより複雑になると、コードの品質が非常に低くなり、実際の泥のボールが発生します。

于 2012-05-21T22:16:44.907 に答える