Question

I'm trying to achieve file transfer over Java socket in Android. It works fine, but when I close the app, it crashes and the console shows nullPointerException. I've tried everything but unable to find the issue!. I've defined ServerSocket as class variable and closing it in onDestroy() method after checking the status of server socket. Here is my code:

package com.vinit.airdrive;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
//Latest saved stub
@SuppressLint("SdCardPath")
public class MainActivity extends Activity {
    Socket socket=null;
    ServerSocket serversocket=null;
    ArrayList<File> fileArray=null;

    @SuppressLint("SdCardPath")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        File file1=new File(Environment.getExternalStorageDirectory()+"/airdrive/Sphere.pdf");
        File file2=new File(Environment.getExternalStorageDirectory()+"/airdrive/Robinson.pdf");
        File file3=new File(Environment.getExternalStorageDirectory()+"/airdrive/Conspiracy.pdf");
        File file4=new File(Environment.getExternalStorageDirectory()+"/airdrive/Expedition.pdf");
        File file5=new File(Environment.getExternalStorageDirectory()+"/airdrive/Xperia.pdf");
        fileArray=new ArrayList<File>();
        fileArray.add(file1);
        fileArray.add(file2);
        fileArray.add(file3);
        fileArray.add(file4);
        fileArray.add(file5);

        Thread trd = new Thread(new Runnable(){
              @Override
              public void run(){
                initializeServer();
                for (int i=0;i<=4;i++){
                    copyFile(fileArray.get(i), fileArray.get(i).getName());
                }
              }
            });
        trd.start();
    }

    private void initializeServer() {
        try {
            serversocket=new ServerSocket(4444);
        } catch (IOException e) {
            e.printStackTrace();
            Log.d("Listen failed", "Couldn't listen to port 4444");
        }
        try {
            socket=serversocket.accept();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            Log.d("Acceptance failed","couldn't accept the server socket connection");
        }
    }

    private void copyFile(File file, String name) {
        FileInputStream fis;
        long filesize=file.length();
        try {
            fis = new FileInputStream(file);
            BufferedInputStream bis = new BufferedInputStream(fis);
            @SuppressWarnings("resource")
            DataInputStream dis = new DataInputStream(bis);
            byte[] mybytearray = new byte[16384];
            OutputStream os;
            os=socket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF(name); //filename is also sent to client
            dos.writeLong(filesize); //file size is also sent to client
            long z=filesize;
            int n=0;

            while((z > 0) && (n = dis.read(mybytearray, 0, (int)Math.min(mybytearray.length, z))) != -1){
                  dos.write(mybytearray,0,n);
                  dos.flush();
                  z -= n;
                }
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } 
    }

    @Override
    protected void onDestroy() {
        // TODO Auto-generated method stub
        super.onDestroy();
        if (serversocket != null) {
            try {
                serversocket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

What could be the problem? Please help!

EDIT: Console output:

    03-22 01:35:38.630: E/AndroidRuntime(12302): FATAL EXCEPTION: Thread-1212
03-22 01:35:38.630: E/AndroidRuntime(12302): java.lang.NullPointerException
03-22 01:35:38.630: E/AndroidRuntime(12302):    at com.vinit.airdrive.MainActivity.copyFile(MainActivity.java:83)
03-22 01:35:38.630: E/AndroidRuntime(12302):    at com.vinit.airdrive.MainActivity.access$1(MainActivity.java:73)
03-22 01:35:38.630: E/AndroidRuntime(12302):    at com.vinit.airdrive.MainActivity$1.run(MainActivity.java:50)
03-22 01:35:38.630: E/AndroidRuntime(12302):    at java.lang.Thread.run(Thread.java:856)

EDIT2:

@Override
protected void onDestroy() {
    // TODO Auto-generated method stub
    if (serversocket != null && socket==null) {
        try {
            serversocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    super.onDestroy();
}
Was it helpful?

Solution 2

Thanks all!! Finally solved the issue. I just inserted a checkpoint before fetching the output stream from socket. Here is the code snippet:

if (socket!=null){
        os=socket.getOutputStream();
        DataOutputStream dos = new DataOutputStream(os);
        dos.writeUTF(name); //filename is also sent to client
        dos.writeLong(filesize); //file size is also sent to client
        long z=filesize;
        int n=0;

        while((z > 0) && (n = dis.read(mybytearray, 0, (int)Math.min(mybytearray.length, z))) != -1){
              dos.write(mybytearray,0,n);
              dos.flush();
              z -= n;
            }
        }
    } catch (FileNotFoundException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

OTHER TIPS

Your crash occurs at this line:

os=socket.getOutputStream();

My guess is that you need to close the Socket object as well. You can either do it in a finally block

try {
    // .. your code here ..
} catch (Exception e) {
    // handle exception
} finally {
    if (socket != null) {
        socket.close()
    }
}

or in the onDestroy() method, for example

@Override
protected void onDestroy() {

    if (socket != null) {
        try {
             socket.close();
        } catch (IOException e) {
             e.printStackTrace();
        }
    }

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

    // call the super method **after** you have closed your objects!
    super.onDestroy();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top