ssrp
ssrp

Reputation: 1266

How to use HTTPPost without a new runnable thread

I have the following code inside my MainAcitivity for logging to the application using username and password taken by a method jsnrqstr.sendRequest(username, password, URL);

loginButton.setOnClickListener(
        new View.OnClickListener()
        {
            public void onClick(View view)
            {
                username = userNameBox.getText().toString();
                password = passwordBox.getText().toString();
                login_state = jsnrqstr.sendRequest(username, password, URL);
                if(login_state.equals("ok")){
                    details.setUserName(username);
                    details.setPassword(password);
                    Toast.makeText(MainActivity.this, "User Verified", Toast.LENGTH_LONG).show();
                    passwordBox.setText("");
                    Intent myIntent = new Intent(MainActivity.this, DashBoardActivity.class);
                    MainActivity.this.startActivity(myIntent);
                }else
                    Toast.makeText(MainActivity.this, "Login Unsuccessful", Toast.LENGTH_LONG).show();
                    passwordBox.setText("");
            }
        });

This method uses the following code for receiving the response from an erlang server which responses with a JSON object and I could receive the login_state from it. Code for jsnrqstr.sendRequest(username, password, URL);

public class JSONRequester {

String state;

public String sendRequest(final String userName, final String password, final String URL){

    new Thread(new Runnable() {
        public void run() {
            HttpClient client = new DefaultHttpClient();
            HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
            HttpResponse response;
            JSONObject json = new JSONObject();
            try{
                HttpPost post = new HttpPost(URL);
                post.setHeader("Content-type", "application/json");
                json.put("username", userName);
                json.put("password", password);
                StringEntity se = new StringEntity( json.toString());
                se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
                post.setEntity(se);
                response = client.execute(post);
                /*Checking response */
                if(response!=null){
                    String temp = EntityUtils.toString(response.getEntity()); //Get the data in the entity
                    //Log.v("response", temp);
                    JsonObject o = new JsonParser().parse(temp).getAsJsonObject();
                    Log.v("response", o.get("state").toString());
                    state = o.get("state").toString();
            }}
            catch(Exception e){
                e.printStackTrace();
                //createDialog("Error", "Cannot Estabilish Connection");
            }
        }
      }).start();
          return state;
}

But I get the following Null-pointer Exception @

if(login_state.equals("ok")){

line which means that I have not returned the login_state value from the above method correctly. As I think This is because by the time the new runnable thread returns the value it is too late. What could I do for fixing this issue?

Upvotes: 1

Views: 1049

Answers (2)

full.stack.ex
full.stack.ex

Reputation: 1747

The problem is between the lines :) - these two:

}).start();

<== HERE!!!

  return state;

The second one gets executed prematurely, while your thread is still running. Concurrency is the solution.

One common Android-specific pattern is AsyncTask - http://developer.android.com/reference/android/os/AsyncTask.html - or its analogs (Thread/Handler etc.)

On click, initiate the process in onPreExecute (code before sendRequest): say, bring up a progress dialog and do the initializations. Your thread's code goes into the doInBackground method and sets the state variable. When done, in onPostExecute, dismiss the progress dialog, and proceed with your login logic: if(/*response*/ state!=null) ...

Upvotes: 1

xshoppyx
xshoppyx

Reputation: 1474

You should use a callback of some sorts that will begin executing your code when the thread has completed if you rely on the return value. Or you can start up the new thread and just wait for it to return before doing anything else.

Upvotes: 1

Related Questions