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