Navjot.jassal
Navjot.jassal

Reputation: 779

java.lang.NullPointerException: Attempt to invoke virtual method 'int java.io.InputStream.read(byte[])' on a null object reference

I am trying to create a Chat Application using WiFip2p.Everything is done in this application. Before send and receive message app was working good. After that, I got this error. I am getting this error when I connect to another device. It shows a null object reference. I don't know why I need a solution can anyone help me thank you.

 public class WiFi_Activity extends AppCompatActivity {


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_wi_fi_);

        FINDVIEWBYID();
        CLICKLISTINER();
    }


    Handler handler=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            switch (msg.what)
            {
                case MESSAGE_READ:

                    byte[]  readbuffer=(byte[])msg.obj;
                    String tempmez=new String(readbuffer,0,msg.arg1);
                    txt_message.setText(tempmez);
                    break;
            }

            return true;
        }
    });

    private void FINDVIEWBYID() {

            btn_onoff=findViewById(R.id.onOff);
            btn_discover=findViewById(R.id.discover);
            btn_send=findViewById(R.id.sendButton);
            listView=findViewById(R.id.peerListView);
            txt_connectionsts=findViewById(R.id.connectionStatus);
            txt_message=findViewById(R.id.readMsg);
            edit_message=findViewById(R.id.writeMsg);

        wifiManager= (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        wifiP2pManager= (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);

        channel=wifiP2pManager.initialize(this,getMainLooper(),null);

        broadcastReceiver=new Wifi_broadcast_reciever(wifiP2pManager,channel,this);

        intentFilter=new IntentFilter();

        intentFilter.addAction(wifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
        intentFilter.addAction(wifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
        intentFilter.addAction(wifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
        intentFilter.addAction(wifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

    }
    private void CLICKLISTINER() {

        btn_onoff.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {


                if (wifiManager.isWifiEnabled())
                {
                    wifiManager.setWifiEnabled(false);
                    btn_onoff.setText("ON");
                }
                else
                {
                    wifiManager.setWifiEnabled(true);
                    btn_onoff.setText("OFF");
                }

            }
        });

        btn_discover.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                wifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {

                        txt_connectionsts.setText("Discovery Started");
                    }

                    @Override
                    public void onFailure(int reason) {

                        txt_connectionsts.setText("Discovery starting failuree"+String.valueOf(reason));
                    }
                });
            }
        });

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 final  WifiP2pDevice wifiP2pDevice=devicearray[position];
                WifiP2pConfig config=new WifiP2pConfig();
                config.deviceAddress=wifiP2pDevice.deviceAddress;
                wifiP2pManager.connect(channel, config, new WifiP2pManager.ActionListener() {
                    @Override
                    public void onSuccess() {

                        Toast.makeText(WiFi_Activity.this, "Connect with"+ wifiP2pDevice.deviceName, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onFailure(int reason) {

                        Toast.makeText(WiFi_Activity.this, "Not connected", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });

        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                String msz=edit_message.getText().toString();
                sendRecieve.write(msz.getBytes());
            }
        });
    }

    WifiP2pManager.PeerListListener peerListListener=new WifiP2pManager.PeerListListener() {
        @Override
        public void onPeersAvailable(WifiP2pDeviceList peerslist) {

            if (!peerslist.getDeviceList().equals(peers));
            {
                peers.clear();
                peers.addAll(peerslist.getDeviceList());

                devicename_array=new String[peerslist.getDeviceList().size()];
                devicearray=new WifiP2pDevice[peerslist.getDeviceList().size()];
                int index= 0;

                 for (WifiP2pDevice device:peerslist.getDeviceList())
                 {
                     devicename_array[index]=device.deviceName;
                     devicearray[index]=device;
                     index++;
                 }

                 ArrayAdapter<String> arrayAdapter=new ArrayAdapter<String>(getApplicationContext(),R.layout.support_simple_spinner_dropdown_item,devicename_array);
                 listView.setAdapter(arrayAdapter);
            }

            if (peers.size()==0)
            {
                Toast.makeText(WiFi_Activity.this, "No discover show", Toast.LENGTH_SHORT).show();
            }
        }
    };

    WifiP2pManager.ConnectionInfoListener connectionInfoListener=new WifiP2pManager.ConnectionInfoListener() {
        @Override
        public void onConnectionInfoAvailable(WifiP2pInfo info) {

            final InetAddress owneraddress= info.groupOwnerAddress;

            if (info.groupFormed && info.isGroupOwner)
            {
                txt_connectionsts.setText("Host");
                serverclass=new Serverclass();
                serverclass.start();
            }
            else if (info.groupFormed)
            {
                txt_connectionsts.setText("Client");
                clientclass = new Clientclass(owneraddress);
                clientclass.start();

            }
        }
    };

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(broadcastReceiver,intentFilter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(broadcastReceiver);
    }

    public class Serverclass extends Thread
    {
        Socket socket;
        ServerSocket serverSocket;

        @Override
        public void run() {

            try {
                serverSocket=new ServerSocket(1111);
                socket=serverSocket.accept();
                sendRecieve=new SendRecieve(socket);
                sendRecieve.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public class Clientclass extends Thread
    {

        Socket socket;
        String host_address;

        public Clientclass(InetAddress hostaddress){

            host_address=hostaddress.getHostAddress();
            socket=new Socket();
            sendRecieve=new SendRecieve(socket);
            sendRecieve.start();
        }

        @Override
        public void run() {

            try {
                socket.connect(new InetSocketAddress(host_address,1111),500);


            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private class SendRecieve extends Thread
    {
        private Socket socket;
        private InputStream inputStream;
        private OutputStream outputStream;

        public SendRecieve(Socket skt)
        {

            socket=skt;

            try {
                inputStream=socket.getInputStream();
                outputStream=socket.getOutputStream();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void run() {

            byte[] buffer=new byte[2048];
            int bytes;

            while (socket!=null)
            {
                try {
                    bytes=inputStream.read(buffer);
                    if (bytes>0)
                    {
                        handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
                    }
                } catch (IOException e) {

                    Log.d("error",e.getMessage());
                }
            }
        }


        public void write(byte[] bytes)
        {
            try {
                outputStream.write(bytes);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

I am getting this error on this part of code:-

  @Override
    public void run() {

        byte[] buffer=new byte[2048];
        int bytes;

        while (socket!=null)
        {
            try {
                bytes=inputStream.read(buffer);
                if (bytes>0)
                {
                    handler.obtainMessage(MESSAGE_READ,bytes,-1,buffer).sendToTarget();
                }
            } catch (IOException e) {

                Log.d("error",e.getMessage());
            }
        }
    }

Upvotes: 0

Views: 12313

Answers (3)

mxl
mxl

Reputation: 667

In my case, even though it was a Bluetooth issue, I assume this might apply to Wifi and other socket connections as well, where after several days of debugging, the problem was in the fact that Android Studio wouldn't compile the code of my app WITHOUT my program performing a (Bluetooth) permission check (checkSelfPermission) before almost every call to anything related to a socket connection, including mBTSocket.connect(). My code ran perfectly on Android >= 12 but crashed on Android 7 and 9 (devices I used to test it and the main devices to run the actual app). As I had to do the check many times within the code, I wrote a method that would do the check and Android Studio accepted this. However, the method would return false after wrongly checking for the SDK version of the platform we're running on, which meant the method mBTSocket.connect() never got called and thus the InputStream and OutputStream of the socket object were unset/null, which lead to this exception. Hope this saves someone some time.

Upvotes: 0

Marcos Vasconcelos
Marcos Vasconcelos

Reputation: 18276

You calling Sendreceiver start before Clientclas run executes, so the following is necessary:

public class Clientclass extends Thread {

Socket socket;
String host_address;

public Clientclass(InetAddress hostaddress){

    host_address=hostaddress.getHostAddress();
    socket=new Socket();
}

@Override
public void run() {

    try {
        socket.connect(new InetSocketAddress(host_address,1111),500);

    sendRecieve=new SendRecieve(socket);
    sendRecieve.start();

    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

Upvotes: 1

mattmess1221
mattmess1221

Reputation: 4444

The only thing I can see as being an issue is that you're catching (and ignoring) errors from getInputStream() and getOutputStream(). The exception is stopping execution, so if getInputStream() errors out, it doesn't get set. Both of your streams would be null.

Since you're at least printing the stacktrace, check for other stacktraces before the actual crash. It may tell you more about what went wrong.

To get around this, I suggest not catching the exception and instead making the constructor throw IOException. If you catch it early, it will cause less problems for you later on.

Edit: I've looked at your classes a bit more, and I see that you don't set the address of the Socket in time. Do that before you get the data streams for it. Not using the fields will work.

private Socket socket;

public SendRecieve(Socket skt) {
    this.socket = skt;
}

@Override
public void run() {
    try {
        InputStream in = socket.getInputStream();
        ... etc
    } ...
}

Upvotes: 3

Related Questions