2011-11-04 17 views
0

我跟着就如何聲明全局contants在幾個職位這裏給出的建議是:宣佈在Java中的全局常量 - 但避免NullPointerException異常錯誤

public class Constants { 

    public static final int i1 = 1; 
    public static final int i2 = 2; 
    } 

我只是有這個類在我的項目,是指像常數這樣的:

in any other class... 
    GlobalsVars.gi1 = Constants.i1; 

(PS我希望這是OK,不需要做任何事情來的常量類像初始化或任何東西。)

但作爲我在這裏發現:使用靜態全局變量的assigning int to Integer不是一個好主意。訪問常量時,我​​的應用程序有時會崩潰。

儘管我發現它真的很奇怪,因爲我的應用程序很小,但可能是Constants類 - 不是活動 - 在某些情況下真的從內存中刪除,儘管我在我的所有活動中都訪問其常量。這就是爲什麼我會認爲它不應該從記憶中刪除。

但是肯定的是,在某些情況下,當訪問Constants.i1值時,我的應用程序崩潰。

以可靠的方式聲明一些常量的最好方法是什麼? (在c-Derivatives中有易於使用的宏)但Android中沒有這樣的東西。

- >所有我需要的是在Java中 「可靠」 常量...

編輯:

添加

聲明GlobalVars類

public class GlobalVars { 
    public static Integer gi1; 
    public static Integer gi2; 
} 

非常感謝

編輯: 新增碰撞記錄

java.lang.RuntimeException:無法啓動活動ComponentInfo {com.xxxx.xxxx/com.xxxx.xxxx.screens.One_screen}:java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java: 1830) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1851) at android.app.ActivityThread.access $ 1500(ActivityThread.java:132) at android.app.ActivityThread $ H.handleMessage(ActivityThread.java :1038) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:150) at android.app.ActivityThread.main(ActivityThread.java:4293 ) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang。方法.invoke(Method.java:507) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:849) at com.android.internal.os.ZygoteInit.main(ZygoteInit。 Java的:607)在dalvik.system.NativeStart.main(本機方法) 產生的原因:在COM在com.xxxx.xxxx.screens.Settings_screen.presentOnScreen(One_screen.java:172) 顯示java.lang.NullPointerException 。 xxx.xxxx.screens.Settings_screen.onCreate(One_screen.java:49) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1072) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1794) 。 ..在One_screen 11多個

和行172:

if (GlobalVars.gi1 == Constants.i1){ 
+1

如果你的變量gi1不是一個靜態變量,所以你不能這樣做NameOfYourClass.gi1,這隻適用於靜態變量;例如:YourClassName.staticVar = Constants.i1;或者:this.gi1 = Constants.i1; – Houcine

+0

我添加了GlobalVars的聲明。在那裏,我聲明變量是靜態的,正如你指出的那樣。 – user387184

+0

這很奇怪。如果你反編譯你的代碼,你會發現你所提到的所有常量都被轉換成了值。 喜歡這個。 Original)int a = Const.A; //值A = 1 編譯)int a = 1; //引用的常量被轉換爲值本身。 檢查你的編譯代碼怎麼樣? – kingori

回答

1

NullPointerException發生,因爲GlobalVars.gi1nullConstants.i1。您應該始終能夠依賴硬編碼的整數值,因爲它們是類定義的一部分。

如果你只是希望存儲少量的長壽命整數變量。我建議看着SharedPreferences來存儲它們(而不是GlobalVars)。

你可以找到更多here

如果您希望只從一個Activity傳遞到另一個數據,看看添加使用Intent.putExtra值到Intent的演員和從Activity.getIntent檢索Intent使用Intent.getExtras在未來Activity獲取額外Bundle

+0

非常感謝您的評論 - 我想那麼無論發生在我的類Contants或GlobalVars中,是因爲它們從內存中刪除?我將以單身身份實施。我也100%肯定,在我的代碼中沒有任何地方將GlobalVars.gi1設置爲空 - 當它在應用程序的開始時被初始化,並且額外的驗證不爲空。順便說一下,在上一個活動中訪問相同的GlobalVars.gi1並不會導致錯誤。它必須以某種方式「鬆散」它的價值,然後從一種活動切換到另一種活動?對? – user387184

+0

你不能*失去你的'常量'值,因爲它們總是被賦予你的硬編碼值!您存儲數據的方式取決於您的需求。粗略地說,按照數據量和複雜性的順序:SharedPreferences - >序列化對象/可分析對象 - >單例 - >數據庫。 –

+0

我使用putExtra以這種方式傳遞參數值,但是我需要一個全局變量持有者對象,這就是爲什麼我使用GlobalVars,所以我可以訪問所有活動中的所有值。這不好嗎? GlobalVars類被導入到所有活動並擁有一些全局值? – user387184

1

你不需要在Java靜態,使他們不斷。你可以使它們成爲finalpublic並以相同的方式訪問它們。但是,不同的是,你必須創建一個帶有引用的類的實例,只要你想訪問那些消耗內存的常量,沒有真正的原因。您可以通過遵循Singleton模式來解決此問題,該模式將創建可通過靜態getInstance()方法訪問的類的單個實例。

+0

非常感謝鏈接 - 我檢查了但我不清楚,因爲分配給靜態變量的單例也可以從內存中刪除 - 這不會導致它的值丟失嗎?因爲它是靜態的,我的意思是? – user387184

+0

如果它是空的,則會創建一個新的,即使它已經消失或被刪除,它會在您下次嘗試獲取它時返回。 – DeeV

+0

哦,是的,當然你是對的:) – user387184

3

您遇到的更一般的問題是如何在多個活動和應用程序的所有部分中保存狀態。一個靜態變量(例如,一個單例)是實現這一點的常用Java方法。然而,我發現Android中更優雅的方式是將您的狀態與應用程序上下文相關聯。如你所知,每個Activity也是一個Context,它是關於其最廣泛意義上的執行環境的信息。你的應用程序也有一個上下文,並且Android保證它將作爲單個實例存在你的應用程序中。

執行此操作的方法是創建您自己的android.app.Application的子類,然後在清單中的應用程序標記中指定該類。現在,Android會自動創建該類的一個實例,並使其可用於整個應用程序。可以從任何上下文使用Context.getApplicationContext()方法(活動還提供了一種方法getApplication(),其具有完全相同的效果)訪問它:

class MyApp extends Application { 

    private String myState; 

    public String getState(){ 
    return myState; 
    } 
    public void setState(String s){ 
    myState = s; 
    } 
} 

class Blah extends Activity { 

    @Override 
    public void onCreate(Bundle b){ 
    ... 
    MyApp appState = ((MyApp)getApplicationContext()); 
    String state = appState.getState(); 
    ... 
    } 
} 

這基本上具有如使用靜態變量相同的效果或singleton,但很好地集成到現有的Android框架中。請注意,這不適用於各個流程(如果您的應用程序是具有多個進程的罕見應用程序之一)。

1

請張貼崩潰的日誌。在閱讀您的其他帖子(您鏈接的那篇文章)後,我確定問題在於別處。例如,在你的other question你一個答案評論提到:

I got a crash report of my app in a place where it compares if (GlobalVars.gi1 == Constants.i1) 

自動裝箱Java5中中+支持這種類型的比較。所給出的代碼普遍適用。

+0

沒有太多的信息,但我把它添加到我的問題中...... – user387184

+0

好吧,所以唯一的辦法是失敗的是,如果GlobalVars.gi1目前爲空。無法將null與一個基元進行比較。沒有看到更多關於如何或在什麼情況下使用的代碼,我不能再有任何幫助。 – Pedantic

+0

當應用程序啓動時,我得到像這樣的數據庫的值:\t GlobalVars.gi1 = appCursor.getInt(appCursor.getColumnIndexOrThrow(MyDBAdapter.KEY1)); \t \t如果(GlobalVars.gi1!= NULL){...一些東西在這裏 \t \t \t \t \t}其他{ \t \t \t GlobalVars.gi1 = Constants.i1; // ensure!= null \t \t} - 就是這樣。然後GlobalVars.gi1的值在此活動中可以毫無問題地訪問。切換到下一個活動我再次訪問該值,這是它崩潰的地方 - 但非常非常罕見 - 甚至在我的測試期間 - 也只在我得到的一個崩潰報告中。這就是爲什麼我更困惑... – user387184