2011年8月4日 星期四

static 的使用(在Android)

看自己放到Android Market上的程式,有錯誤報導。

java.lang.NullPointerException
at com.sni.Prayer.PrayerData.Update(PrayerData.java:148)
at com.sni.Prayer.WordActivity$6.onClick(WordActivity.java:173)
at android.view.View.performClick(View.java:2461)
at android.view.View$PerformClick.run(View.java:8888)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)

而錯誤的程式是:

private static Cursor getWords(int prayerId) {
Cursor cursor=null;
try {
cursor = database.query(WORDS_TABLE, null, PRAYER_ID_IS+prayerId, null, null, null, null);
} catch(SQLException e) {
Log.e(TAG,e.getMessage());
}
return cursor;
}

Null Exception, 那當然就是database了,但是,為什麼如此? 執行到這一行,應該早就開啟了,為什麼沒有開啟呢? 當然,簡單加個 if(database==null) 的判斷是容易的,我的想法是,一定要找出原因,而且,不必執行的就不必執行,不要執行重覆的判斷。經過分析,發現:
自己很喜歡用static 變數,覺得
  1. 當作global來用
  2. 不必new就可以使用
  3. 只有一份記憶體,省空間
這個database類別,被自己搞成,每一個member都是static, 自己覺得不妥,但是懶得改,真是糟糕,給自己一個警惕。如果都是static, 沒有instance, 是否在記憶體管理時,會被整個御載,御載後再載入時,其static data member的值是否就沒了,變成null了,當然,改成每次讀的時候都check,這是一個方式,但是,這麼多了許多判斷。因此,保留data member 為static, 但是要使用這個資料的函數,都取消,不是static, 保留那些完全沒有使用資料成員的函數為static。每個Activity在調用時,必須先創建(new)一個instance。而在Constructor中加入判斷資料庫database是否為空的判斷。…OK
同時也想到,記憶體管理是以class, Activity為單位。因此,保留每一個類別的”完全”獨立,有助於記憶體管理。因此,將所有static改成private, 或是移到不是Activity的class中。

沒有留言:

張貼留言