在一类效用函数中初始化静态变量

时间:2012-05-21 21:58:41

标签: android

对于我的Android应用程序,我编写了一个由应用程序中各种活动所需的实用程序函数组成的类。在这个类中,我需要一个上下文变量(用于处理文件)和一个首选项管理器的实例和首选项编辑器。还需要一个长整数,将当前日期重新设置为时间戳:

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();
}

一种方法是在每个使用它的活动中创建这个类的实例,但我不想这样做。还有其他方法吗?

4 个答案:

答案 0 :(得分: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。单身人士在某些情况下很有用,但你应该知道使用它们所涉及的陷阱。

答案 1 :(得分: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();
}

单身人士是编程事物的一种糟糕方式,它使得测试非常困难。即使你还没有使用测试,也不要使用单身,当事情变得更加复杂时,会导致代码质量非常差,真正的泥球。

答案 2 :(得分: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
     }

}

答案 3 :(得分: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();
    ...
}

您可以动态计算/推断的其他变量。它可能意味着更多垃圾收集,但在内存管理方面应该相对安全。