作为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()从给定上下文中获取应用程序上下文。
您应该编写一个单例类,如下所示:
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