2012-05-21 73 views
0

对于我的Android应用程序,我编写了一个由应用程序中各种活动所需的实用函数组成的类。在这个类中,我需要一个上下文变量(for用文件)和偏好经理和偏好editor.Also,一个长整型,因为需要一个时间戳represnting当前日期的实例工作:在一类实用函数中初始化静态变量

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

一种方法是创建它的地方使用这个类在每一个活动的一个实例,但我不知道,不想做that.Any另一种方法是可能的吗?

+0

你究竟在犯什么错误?你是否熟悉单身人士的想法? –

+0

我收到了有关sharedPrefs和editor的空指针异常。我不熟悉这个概念,这就是为什么我问:) – user1107888

+0

只是一个提示:小心你使用Context作为静态变量。这很容易造成内存泄漏。确保当您切换到新的上下文时它被清零或取消引用。 – Codeman

回答

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。在某些情况下,单身人士可能会很有用,但您应该意识到使用它们所涉及的陷阱。

+0

当您将Utility设计模式(仅限静态方法,私有构造函数)与单例设计模式(具有实例方法的独特实例化类)混合使用时,您的回答有点混乱。而且,单例实例访问器更加标准化地命名为getInstance并且应该被同步。 – Snicolas

+0

我没有演示Utility模式,这只是我根据OP的措辞选择的名称。注意''level'是一个实例变量;我可以添加相应的非静态getter和setter,但没有显示。你可以调用实例访问器来满足你的任何需求,并不要求它被称为'getInstance()'。 –

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

单身人士的编程的东西一个坏的方式,它使事情很难测试。即使你还没有使用测试,不要使用单身测试,当事情变得更加复杂时,会导致质量很差的代码和真正的泥球。

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 
    } 

} 
0

不过已经有了一堆贴在这里很好的建议,但我想另一个这些'utility'/'helper'函数的方法就是简单地传递你需要的逻辑参数。在你的情况,在努力让自己在当地的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(); 
    ... 
} 

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