2012-05-21 114 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(); 
    ... 
} 

就可以計算出/推斷在飛行的其他變量。這可能意味着更多的垃圾收集,但在內存管理方面應該相對安全。