2011-06-30 15 views
0

作爲新手Android開發人員,我遇到了一個奇怪的問題。我想創建一個類,其他類 - 活動 - 哪些方法可用於以某種特殊方式處理文件。爲了簡單起見,我們會記錄一些東西。如果我做了一個活動中以下內容(的OnClick聽衆爲例),一切都工作得很好:openFileOutput在單例類中不能正常工作 - 想法/解決方法?

FileOutputStream fOut = openFileOutput("somefile", MODE_PRIVATE); 
OutputStreamWriter osw = new OutputStreamWriter(fOut); 
osw.write("Very important foobar"); 
osw.flush(); 
osw.close(); 

但是,當我試圖罩住到一些類並創建單這樣的:

public class Logger extends BaseActivity { 
//BaseActivity is the "init" class which extends Activity 

public static final Logger INSTANCE = new Logger(); 
private Logger() { 
// singleton 
} 

public boolean doLog (String whatToLog) { 
try { 
    FileOutputStream fOut = openFileOutput("somefile", MODE_PRIVATE); 
OutputStreamWriter osw = new OutputStreamWriter(fOut); 
osw.write(whatToLog); 
osw.flush(); 
osw.close(); } 
    catch (IOException ioe) { ioe.printStackTrace(); } 
    return true; } 

和來自其它活性(與openFileOutput在線)調用它像的NullPointerException該

Logger.INSTANCE.doLog("foobar"); 

應用chrashes。我想這是因爲在這裏不正當地使用單例/活動,現在重寫代碼以作爲服務運行。但也許有更好的想法來解決一個問題?或者一些解決方法?

感謝您的貢獻提前!

回答

3

您基於您沒有作爲Activity開始的Activity的單身人士。因此,它沒有有效的上下文,這對於IO調用是必需的。請參閱Blundell的answer以獲得更好的單例,並進行一次更改:根據android.app.Application javadoc,您的單例應通過Context.getApplicationContext()從給定上下文獲取應用程序上下文。另一個例子見why does AndroidTestCase.getContext().getApplicationContext() return null

0

我很確定你的錯誤不是來自你提到的那一行。

一個空指針異常發生在形式

A.B or A.B() 

其中A是空的聲明。在這條線上你的班上沒有這種東西。

請仔細檢查堆棧跟蹤,發送並指示行號。

不要忘記在所有這些之前保存文件。

問候, 斯特凡

+0

日誌說它'相當簡單: 06-30 17:13:43.614:ERROR/AndroidRuntime(5250):顯示java.lang.NullPointerException 06-30 17點13分:43.614:ERROR/AndroidRuntime(5250):at android.content.ContextWrapper.openFileOutput(ContextWrapper.java:158) 06-30 17:13:43.614:ERROR/AndroidRuntime(5250):at org.aclient.my。 Logger.doLog(Logger.java:26) 06-30 17:13:43.614:ERROR/AndroidRuntime(5250):at org.aclient.my.AndroidClientMainActivity.onClick(AndroidClientMainActivity.java:79) – Nick

+0

其中第26行是FileOutputStream fOut = openFileOutput(「somefile」,MODE_PRIVATE); 和第79行是Logger.INSTANCE.doLog(「foobar」); – Nick

+0

儘管我已經忽略了較短代碼的異常處理,但已更新它 – Nick

0

你應該寫一個單獨的類是這樣的:

import android.content.Context; 
import android.util.Log; 

public final class SomeSingleton implements Cloneable { 

private static final String TAG = "SomeSingleton"; 
private static SomeSingleton someSingleton ; 
private static Context mContext;  

/** 
* I'm private because I'm a singleton, call getInstance() 
* @param context 
*/ 
private SomeSingleton(){ 
     // Empty 
} 

public static synchronized SomeSingleton getInstance(Context context){ 
    if(someSingleton == null){ 
     someSingleton = new SomeSingleton(); 
    } 
    mContext = context.getApplicationContext(); 
    return someSingleton; 
} 

public void playSomething(){ 
    // Do whatever 
      mContext.openFileOutput("somefile", MODE_PRIVATE); // etc... 
} 

public Object clone() throws CloneNotSupportedException { 
    throw new CloneNotSupportedException("I'm a singleton!"); 
} 
} 

然後調用它像這樣(取決於你來自哪裏,叫):

SomeSingleton.getInstance(context).playSomething(); 
SomeSingleton.getInstance(this).playSomething(); 
SomeSingleton.getInstance(getApplicationContext()).playSomething(); 

編輯:請注意,這個單身人物的工作原理是因爲它不是基於Activity,並且它從任何實例化它的人(如另一個正確啓動的Ac tivity)。你原來的單身失敗,因爲它從來沒有作爲一個活動開始,所以它沒有一個有效的上下文。 -cdhabecker

+0

危險,因爲此單例只會綁定到請求的第一個上下文。 –

+0

@Dave啊,明白了。我正在倉促:)編輯單身。 – Blundell

+0

謝謝,它似乎是有道理的,但mContext =上下文線無法編譯 - 不能靜態引用非靜態字段mContext \t - 和mContext.openFileOutput(「somefile」,MODE_PRIVATE);也(因爲我們沒有正確的上下文,我想) – Nick

0

你正在正確地使用你的班級我不認爲它正在做你打算做的事。您的openFileOutput調用失敗,因爲您的單例沒有上下文。它不會經歷初始化生命週期階段,也不會建立上下文。

我建議您創建一個服務以允許日誌寫入,並在要記錄的對象的「靜態」上下文中綁定到該服務,以確保日誌請求是原子的。

+0

我不認爲有可能有一個擴展活動的單例模式?當系統通過onCreate等獲得訪問時 – Blundell

+0

謝謝!實施服務應該有效,我現在正在做。但我還沒有用上面的代碼對它進行整理。我如何將上下文傳遞給單身人士? – Nick

+1

@尼克我告訴你尼克看到我的答案。 – Blundell

0

您應該在OnCreate方法中調用doLog,而不是在Activity的構造函數中。 在此之前,它沒有@Dave G所說的上下文。

問候, 斯特凡

相關問題