xXJohnRamboXx
xXJohnRamboXx

Reputation: 739

using AsyncTask for socket

I have this android code:

private class myTask extends AsyncTask<String, String, String> {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

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

       try {

             client = new Socket("192.168.1.2", 4444); 
             oos = new ObjectOutputStream(client.getOutputStream());
             ois = new ObjectInputStream(client.getInputStream());

             oos.writeUTF("LOGIN");
             oos.flush();

             String emailText = email.getText().toString();
             oos.writeUTF(emailText);
             oos.flush();

             String passwordText = password.getText().toString();
             oos.writeUTF(passwordText);
             oos.flush();

             string = ois.readUTF();

       }catch (ConnectException e){
           return "Host not found";
       }catch (IOException e) {
           return "Exception Caught";
       }
       return null;
    }

    @Override
    protected void onPostExecute(String result) {

        super.onPostExecute(result);   

        if ("Host not found".equalsIgnoreCase(result)){ 
            Toast.makeText(getApplicationContext(), "Host not found" ,Toast.LENGTH_LONG).show();
        }else if("Exception Caught".equalsIgnoreCase(result)){
            Toast.makeText(getApplicationContext(), "Connection error" ,Toast.LENGTH_LONG).show();
        }else{
             Toast.makeText(getApplicationContext(), "Connection established" ,Toast.LENGTH_LONG).show();
        }
        Toast.makeText(getApplicationContext(), string ,Toast.LENGTH_LONG).show();
        if(string.equals("Login successfully Done!")){
            startActivity(new Intent(Login.this, User.class));
        }

    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_login);
    register = (TextView)findViewById(R.id.register);
    login = (Button)findViewById(R.id.login);
    email = (EditText)findViewById(R.id.email);
    password = (EditText)findViewById(R.id.password);
    connection = (TextView)findViewById(R.id.connection);



    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
                .add(R.id.container, new PlaceholderFragment())
                .commit();
    }

    register.setOnClickListener(new View.OnClickListener(){

        @Override
        public void onClick(View arg0) {
            startActivity(new Intent(Login.this, Register.class));
        }
    });

    login.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

            new myTask().execute();

        }
    });
}

but my connection create everytime i click on login button. I want my app connect to server at start and then when i press login button it sends request to server..How i need to change my code?

thanks

Upvotes: 0

Views: 408

Answers (2)

Jonathan
Jonathan

Reputation: 3457

The problem here is that you're creating the socket in your doInBackground() method. This means that every time you execute an instance of AsyncTask that socket will be recreated. What you probably want to do is subclass Application or some sort of singleton and initialize your socket in there. Then make your AsyncTask do something like:

doInBackground(Object... params) {
    // do stuff
    Socket socket = Application.getSocket();
    // do stuff with the socket
}

This introduces a bit of complexity as you need to handle properly opening/closing your socket at the proper points in your application lifecycle, but it is the cleanest solution that comes to mind.

Upvotes: 1

Gabe Sechan
Gabe Sechan

Reputation: 93561

I think the easiest way to do that would be to move away from AsyncTasks and move to Threads. Create a new Thread in your onCreate function that creates the socket and connects it, then have it wait for a notification from the UI thread (easiest way to do this is to wait on a semaphore or message queue). Then have the onClick of the button notify the socket thread that it needs to login. With this design, you'll have it connect at startup but not login until you request it.

Your biggest worry here is if your server times out your connection for inactivity. But I assume you have control of the server to prevent that.

Upvotes: 1

Related Questions