user3341858 user3341858 - 6 months ago 22
Android Question

DataOutputStream nullpointer exception

I am getting a

NullPointerException
on a
DataOutputStream
in Android.

I first wrote some code to write out files in Java using
DataOutputStream
. Everything worked perfectly. The I imported the code to an Android project and I am getting some weird behavior.

The only code I changed to be android specific is how I get the directory.

So what exactly is happening is: I am creating the
DataOutputStream
and then I am closing it. That is all for now. I figure it is a good first step to test if stream was opened correctly is to close it.

DataOutputStream
is a class instance variable.

When I call close on it in same method it closes fine. When I call close on it from a different method, it gets
NullPointerException
. But doing these same things in Java did not cause a problem, though they did in Android.

public class WavFileOutStream {

private DataOutputStream stream;

public WavFileOutStream(String fileName)
{

// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_RINGTONES), fileName);
if (!file.mkdirs()) {
Log.e("trace", "Directory not created");
}

try {
stream = new DataOutputStream(new FileOutputStream(file));

if(stream==null)
{
Log.i("trace","Null Stream!");
}

//<--PROBLEM LINE 1-->
//If I call close from this line I get NO nullPointer
//stream.close();


} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//<--PROBLEM LINE 1-->
//If I call close from this line I get a nullPointer
//I comment out other close() first
close();

}

public void close()
{
try {
stream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


Error:

02-24 12:49:39.229: E/AndroidRuntime(11539): FATAL EXCEPTION: main
02-24 12:49:39.229: E/AndroidRuntime(11539): Process: com.example.ringtonegenerator, PID: 11539
02-24 12:49:39.229: E/AndroidRuntime(11539): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ringtonegenerator/com.example.ringtonegenerator.MainActivity}: java.lang.NullPointerException
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2195)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread.access$800(ActivityThread.java:135)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.os.Handler.dispatchMessage(Handler.java:102)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.os.Looper.loop(Looper.java:136)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread.main(ActivityThread.java:5017)
02-24 12:49:39.229: E/AndroidRuntime(11539): at java.lang.reflect.Method.invokeNative(Native Method)
02-24 12:49:39.229: E/AndroidRuntime(11539): at java.lang.reflect.Method.invoke(Method.java:515)
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
02-24 12:49:39.229: E/AndroidRuntime(11539): at dalvik.system.NativeStart.main(Native Method)
02-24 12:49:39.229: E/AndroidRuntime(11539): Caused by: java.lang.NullPointerException
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.example.ringtonegenerator.WavFileOutStream.close(WavFileOutStream.java:178)
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.example.ringtonegenerator.WavFileOutStream.<init>(WavFileOutStream.java:43)
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.example.ringtonegenerator.WavFileWriter.writeWave(WavFileWriter.java:10)
02-24 12:49:39.229: E/AndroidRuntime(11539): at com.example.ringtonegenerator.MainActivity.onCreate(MainActivity.java:23)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.Activity.performCreate(Activity.java:5231)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
02-24 12:49:39.229: E/AndroidRuntime(11539): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2159)
02-24 12:49:39.229: E/AndroidRuntime(11539): ... 11 more

Answer

If you throw an exception when the stream is created, the stream will still be null and you will still call close. There is no check for null there, so it will throw NPE.

public void close()
{
    if(stream != null){
        try {
            stream.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}