0
public class checkSchoolCodeQuery extends AsyncTask<String, Integer, String> {
    EditText etSchoolCode = (EditText) findViewById(R.id.etSchoolCode);
    String schoolcode = etSchoolCode.getText().toString();
    String isValid = "didn run";
    @Override
    protected String doInBackground(String... params) {

        final ParseQuery<ParseObject> query = ParseQuery.getQuery("Schools");

        query.whereEqualTo("schoolcode", schoolcode);
        query.countInBackground(new CountCallback() {
            @Override
            public void done(int i, ParseException e) {
                if (e == null) {
                    if (i == 1) {
                        // Check if expiry date is greater than today's date
                        query.getFirstInBackground(new GetCallback<ParseObject>() {
                            @Override
                            public void done(ParseObject parseObject, ParseException e) {
                                if (e == null) {
                                    Date expiryDate = parseObject.getDate("expirydate");
                                    Date todaysDate = new Date();
                                    System.out.println(expiryDate);
                                    if (expiryDate.after(todaysDate)) {
                                        isValid = "true";
                                    } else {
                                        isValid = "false";

                                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext())
                                                .setMessage("Your school doesnt have access");
                                    }

                                } else {
                                    System.out.println("There was an error when checking if School Code was valid");
                                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext())
                                            .setMessage("There was an error when checking if School Code was valid");
                                    AlertDialog alertDialog = alertDialogBuilder.show();
                                    isValid = "didnt run";
                                }
                            }
                        });
                    } else {
                        isValid = "false";

                        // Create Alert Dialog to show error text
                        AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext())
                                .setMessage("The School Code is invalid");
                        AlertDialog alertDialog = alertDialogBuilder.show();

                    }
                } else {
                    isValid = "didnt run";
                    System.out.println("There was an error when checking if School Code was valid");
                    // Create Alert Dialog to show error text
                    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext())
                            .setMessage("There was an error when checking if School Code was valid");
                    AlertDialog alertDialog = alertDialogBuilder.show();

                }
            }
        });

    return isValid;

    }



    @Override
    protected void onPostExecute(String aString) {

        if (aString == "true") {
            System.out.println("The school code is valid");
        } else if (aString == "false") {
            System.out.println("The school coe is invalid");
        }
        else {
            System.out.println("There was an error");
        }

    }
}

When I run my code, the isValid variable doesn't update, so it uses the initial value of the isValid string. Am I implementing the AsyncTask wrongly or did I miss out something? How do I make the variable update in an AsyncTask? Please help as I am a beginner in programming. I've checked other questions but they don't apply to my case; they are all advanced scenarios and I don't understand their code. I'm just looking for a simple fix to my problem.

Boann
  • 48,794
  • 16
  • 117
  • 146
  • Please use enum to define your state, using string to define your state is bad code !!, secondly use TextUtils.equals(a,b) to compare two strings. – dex Oct 27 '15 at 19:52
  • It still gives me the same output, comparing the strings is not my problem, the problem is still that the variables don't get updated in the asynctask – user3147316 Oct 27 '15 at 19:58
  • attach debugger, check if your code is actually hitting it or not, then update the string. – dex Oct 27 '15 at 19:59

1 Answers1

0

You've made this too complicated by trying to use too many layers of background threads.

AsyncTask executes the doInBackground method in a background thread. Within that, you start a query in yet another background thread to update the isValid variable, then you immediately return the current (unchanged) value of isValid as the result of the AsyncTask, before the query has run. By the time the query callback is called, the value of isValid will not be looked at again since return isValid; has already executed.

The solution is, since you're already on a background thread within AsyncTask.doInBackground, don't use the query object's methods that execute on additional background threads. Within AsyncTask.doInBackground, execute the queries directly. This will also let you reduce the scope of isValid to a local variable instead of a field. Or, since ParseQuery's various inBackground methods are apparently already designed specifically for use with the Android UI thread, maybe you can just use one of those without AsyncTask.

I've never done Android programming so I'm not familiar with any of these classes, so there could another possibility I'm missing.

Another issue that is not currently causing a problem in your code, but it easily could do because it's so flimsy, is trying to use a String to store program state information. It's also dodgy to compare it with == instead of equals, though currently that's harmless as the String literals are interned. Maybe that's just test code while you're trying to diagnose the other problem, but if not then it would be better to implement such a tri-state with an enum, or a nullable Boolean, or something:

private enum Result { VALID, INVALID, DID_NOT_RUN }
private Result validity = Result.DID_NOT_RUN;
...
Boann
  • 48,794
  • 16
  • 117
  • 146