As a novice Android developer, I've faced a bit strange problem. I want to create a class, which methods other classes-activities-whatever could use for working with files in some special way. Let`s say for simplicity we would be logging some stuff. If I do following within an activity (in OnClick listener for example), everything works just fine:
FileOutputStream fOut = openFileOutput("somefile", MODE_PRIVATE);
OutputStreamWriter osw = new OutputStreamWriter(fOut);
osw.write("Very important foobar");
osw.flush();
osw.close();
But when I try to enclose that into some class and create singleton like that:
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; }
and call it from other activity like that
Logger.INSTANCE.doLog("foobar");
app chrashes with NullPointerException (at line with openFileOutput). I suppose it`s because of improper use of singleton/activity here and now rewriting the code to run as a service. But maybe there are some better ideas to solve an issue? Or some workarounds?
Thanks for your contributions in advance!
You based your singleton on an Activity that you didn't start as an Activity. Therefore, it doesn't have a valid Context, which is necessary for the IO calls. See Blundell's answer for better singleton, with one change: As per android.app.Application javadoc, your singleton should get the application context from the given context via Context.getApplicationContext(). See why does AndroidTestCase.getContext().getApplicationContext() return null for another example.
You're using your class properly I don't think that it is doing what you intend. Your call to openFileOutput is failing because your singleton doesn't have a context. It will not have gone through the initialization life cycle phases and no context will have been established.
I would recommend that you create a service to allow for log writing and bind to that service in a "static" context on the objects you want to log with making sure that log requests are atomic.
You should call
doLog
in OnCreate method, not in constructor of your Activity. Before that, it doesn't have a context as @Dave G said.Regards, stéphane
You should write a singleton class like this:
Then you call it like this (depending on where you call it from):
Edit: Note that this singleton works because it is not based on Activity and it gets a valid Context from whoever instantiates it (like another properly started Activity). Your original singleton failed because it never got started as an Activity, so it didn't have a valid Context. -cdhabecker
I am pretty sure your error doesn't come from the line you mention.
A null pointer exception happens in a statement of the form
where A is null. And there is no such thing in your class at this line.
Please double check stack trace, send it and indicate line numbers.
Don't forget to save your files before all that.
Regards, Stéphane