1

What I want

I'm determining whether or not a user is in my database.

To do that, I look at the JSON response from my webpage. This is determined in the inner-class HasUser which extends AsyncTask<String, Void, String>.

It's a running a background process to find the user.

I want to get the result of that back in my main method. So the background process should look for the user, and then a boolean back in my main method should be true if the user was found.

What I've done

I have added a method to the HasUser class called hasUser() which returns whether or not the user was found (as a boolean). The class has an instance variable called found which is assigned in the onPostExecute method.

So in my main method, I execute the background process, then assign the boolean value of whether or not the user was found to be hasUser.hasUser(). It's like this:

private class HasUser extends AsyncTask<String, Void, String> {

    boolean found = false;

    String user;
    public HasUser(String user) { this.user = user; }

    @Override
    protected String doInBackground(String... params) {
        String result = "";
        // return the JSON string response from webpage
    }

    @Override
    protected void onPostExecute(String result) {
        try {
            // JSON stuff

            if (/*success == 0*/) { // user not found
                found = false;
            } else { // found user
                found = true;
            }
        } catch(JSONException e) {
            // handle exception
        }
    }

    public boolean hasUser() {
        return found;
    }

    @Override protected void onPreExecute() { }
    @Override protected void onProgressUpdate(Void... values) { }
}

And then in my main method, I attempt to get the appropriate result:

public void logIn() {
    HasUser hasUser = new HasUser("username");
    hasUser.execute();
    boolean found = hasUser.hasUser();
}

Problem

Even when the user is correctly found (verified by toasting the success message), the found variable in logIn() will always be false because it is assigned before the background process is complete.

Is there any way I can make sure the background process is complete before I retrieve the variable from it (I know this is contrary to the meaning of the background process)? Or how else can I achieve this? I want a boolean back in my main method to be the proper result.

Michael Yaworski
  • 13,410
  • 19
  • 69
  • 97

2 Answers2

2

Use a listener interface to pass back the result, implement your AsyncTask like this:

public class ExampleTask extends AsyncTask<Void, Void, Boolean> {

    public interface TaskListener {
        public void onFinished(boolean success);
    }

    private final TaskListener listener;

    private ExampleTask(TaskListener listener) {
        this.listener = listener;
    }

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

        boolean result = doWork();

        return result;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);

        if(this.listener != null) {
            this.listener.onFinished(result);
        }
    }
}

And you can use it like this:

ExampleTask task = new ExampleTask(new ExampleTask.TaskListener() {
    @Override
    public void onFinished(boolean success) {
        // Do whatever you want with the result
    }
});
task.execute();
Xaver Kapeller
  • 49,491
  • 11
  • 98
  • 86
1

The problem is that AsyncTask is asynchronous that onPostExecute is called when the background thread is done but you can make the AsyncTask synchronous by using the get method after you execute it but it will wait for your AsyncTask to be done before executing the next line(causes lag bad idea).

if you dont want your AsyncTask synchronous with your Main thread.

what you need is to create a CallBack method(interface) that implements in your activity main. then pass the reference of the interface in your HasUser constructor and pass the boolean value in the interface method from your on onPostExecute.

Rod_Algonquin
  • 26,074
  • 6
  • 52
  • 63