openFileOutput在单例类中不能正常工作 – 想法/解决方法?

作为新手Android开发者,我遇到了一个奇怪的问题。 我想创建一个类,它可以处理其他类 – 活动 – 用于以某种特殊方式处理文件的任何方法。 我们为了简单起见,我们会记录一些东西。 如果我在一个活动中做跟踪(例如在OnClick监听器中),一切正常:

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

并从其他类似的活动中调用它

 Logger.INSTANCE.doLog("foobar"); 

应用程序因NullPointerException而崩溃(与openFileOutput一致)。 我想这是因为在这里不正确使用单例/活动,现在重写代码以作为服务运行。 但也许有一些更好的想法来解决问题? 还是一些解决方法?

感谢您的贡献!

您将单例基于您未作为活动启动的活动。 因此,它没有有效的上下文,这是IO调用所必需的。 有关更好的单例,请参阅Blundell的答案 ,只需更改一次:根据android.app.Application javadoc,您的单例应通过Context.getApplicationContext()从给定的上下文中获取应用程序上下文。 了解为什么AndroidTestCase.getContext()。getApplicationContext()为另一个示例返回null 。

我很确定你的错误不是来自你提到的那一行。

在表单的语句中发生空指针exception

 AB or AB() 

其中A为空。 在这一行中,你class上没有这样的东西。

请仔细检查堆栈跟踪,发送并指示行号。

不要忘记在所有这些之前保存文件。

此致,Stéphane

你正在使用你的class级我不认为它正在做你想要的。 您对openFileOutput的调用失败,因为您的单例没有上下文。 它不会经历初始化生命周期阶段,也不会建立上下文。

我建议您创建一个服务以允许日志写入并在要记录的对象的“静态”上下文中绑定到该服务,以确保日志请求是primefaces的。

您应该在OnCreate方法中调用doLog ,而不是在Activity的构造函数中调用doLog 。 在此之前,它没有@Dave G所说的背景。

此致,stéphane

你应该写一个像这样的单例类:

  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,而是从实例化它的人那里得到一个有效的Context(就像另一个正确启动的Activity)。 您的原始单例失败,因为它从未作为活动启动,因此它没有有效的上下文。 -cdhabecker