Search code examples
javaandroidsocketsandroid-asynctasksocketserver

getInputStream in Async Task


I have an Activity which calls an Async task to accept socket connections through a predefined InetAddress.

The Async task calls another Async task to listen for messages in. but it hangs on the get input stream

I have been racking my brain for hours and cannot work out why it is hanging...any help please.

public void startSocketListener(InetAddress groupOwnerAddress) {
    // TODO Auto-generated method stub
    AcceptClientThread accept;
    try {
        accept = new AcceptClientThread();
        accept.execute();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

public class AcceptClientThread extends AsyncTask<Void, String, String>{

    public AcceptClientThread() throws IOException{

    }

    @Override
    protected void onCancelled() {
        // TODO Auto-generated method stub
        try {
            serverSocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            Log.e("CONNECTION ERR", "Could not close serverSocket " + e.toString());
        }
        super.onCancelled();
    }

    @Override
    protected String doInBackground(Void... params) {

        try {
            serverSocket = new ServerSocket(port);
        } catch (IOException e) {
            Log.e("CONNECTION ERR","Could not listen on port: " + port);
            onCancelled();
        }

        while (listening){
            try {
                Log.i("CONNECTION", "AWAITING CONNECTION TO CLIENT");
                Socket newSocket = serverSocket.accept();
                Log.i("CONNECTION", "CONNECTED TO CLIENT");
                ListenerThread lThread = new ListenerThread(newSocket);
                lThread.execute("Do it");
                Log.i("CONNECTION", "ACCEPTED CLIENT");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                onProgressUpdate("could not accept client");
            }

        }
        Log.i("CONNECTION", "close socket");
        try {
            serverSocket.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return "table connected";
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        // received data is first element in the String
        //Toast.makeText(KitchenActivity.this, values[0], Toast.LENGTH_SHORT).show();
    }

}

public class ListenerThread extends AsyncTask<String, Order, Void> {

    private Socket socket;
    ObjectInputStream ois;

    public ListenerThread(Socket socket){
        this.socket = socket;
        try {
            ois = new ObjectInputStream(this.socket.getInputStream()); //hangs here
        } catch (StreamCorruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

Solution

  • According to The Docs

    Threading rules

    There are a few threading rules that must be followed for this class to work properly:

    The AsyncTask class must be loaded on the UI thread. This is done automatically as of JELLY_BEAN. The task instance must be created on the UI thread.

    You can handle this by calling your new Thread in the onPostExecute() of your first AsyncTask after your accept() is successful, as onPostExecute() runs on the UI

    Also, without looking at it more, I believe that you would want to break out of your while loop in the first task after it accepts the request. Then when you need to make another connection you create a new instance of this task in your UI and execute it again. I'm not positive about that last part without looking at it longer but that seems right