当前位置: 首页 > 面试题库 >

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

阙庆
2023-03-14
问题内容

作为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()从给定上下文中获取html" target="_blank">应用程序上下文。

您应该编写一个单例类,如下所示:

 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,并且从实例化它的任何人(例如另一个正确启动的Activity)都可以获取有效的Context。您的原始单例失败,因为它从未作为活动开始,因此没有有效的上下文。-cdhabecker



 类似资料:
  • 我正在为我的android乞丐项目创建一个1对1扑克芯片计数器应用程序。当我按下任何调用displayBetPlayer1或displayBetPlayer2的按钮(+、-、Bet/Rise)时,我会收到一个运行时错误,所以我知道问题出在这些方法上。我还看到导入语句有一些不对劲的地方,但我对此太陌生,不明白是什么。有人知道问题出在哪里吗?(我将在注释中发布activity_main.xml,因为它

  • 我试图用Spring Boot和ReactJs构建一个CRUD应用程序,但我在“Edit”方法中遇到了一些错误。当我试图编辑一个用户时,我在网络选项卡中得到一个404错误,我设法在框中写入,当我想保存而不是编辑我选择的用户时,一个新的添加。“add”方法工作正常,但我认为这是方法之间的重叠。我将把代码留在这里:

  • 问题内容: 我正在尝试Java线程方法的示例。但是我发现即使线程已经启动,该方法仍在返回。有人可以告诉我我在做什么错吗?这是代码片段。 问题答案: 如果我的记忆很好,那么java在线程切换之间会有很长的时间间隔,因此isAlive可能会失败,因为线程 尚未 激活。尝试在thread.start()和thread.isAlive()之间添加一些等待时间

  • 我试图在一个变量中保存得分为80分或80分以上的学生的姓名,但我无法使用filter进行保存,它返回整个对象,尽管我指定只打印这些对象的键值,即这些学生的姓名。 我的代码: 我怎样才能得到得分在80分以上的学生的名字?

  • 我在以下问题上显示复利和贷款时遇到问题。我必须有一个抽象的超类和两个方法,一个是集合,一个是获取存储原则量,一个是抽象集合,一个是获取存储速率和年份。当我运行这个项目时,我不知道我做错了什么,无论我做什么,大院和贷款都保持在0.0。请帮忙!!谢谢哦,我还必须创建对象的引用,我知道怎么做。注:我最初有公共双年费和公共双年费,但由于不起作用,我创建了第2年费率2等。

  • 我正试图在按下某个按钮时弹出一个警报对话框。我首先使用了Android Developer的示例代码而不是'这不起作用,所以我根据在这个站点上发现的情况进行了更改,但是现在我的程序在按下按钮后被迫停止。 就你的知识而言,这是在第二个不同于主要的活动中完成的。不确定这是否重要.... ‘ 碰撞日志:“03-25 19:34:24.373:E/AndroidRuntime(18828):致命异常:ma