0

I want to check if a user is registered or not in a database, and if it is get the information of the user.

Normally, when I retrieve the information from the server, I put in the Json a variable saying if the user exists or not. Then in onPostExecute(Void result) i treat the Json, so i don't need the AsyncTask to return any value.

Before I was calling the AsyncTask as follows:

task=new isCollectorRegistered();
task.execute();

But now i'm trying a different approach. I want my asynktask to just return a boolean where i called the AsyncTask.

the AsyncTask looks as follows:

public class isCollectorRegistered extends AsyncTask<Void, Void, Void> {

    private static final String TAG_SUCCESS = "success";
    int TAG_SUCCESS1;
    private static final String TAG_COLLECTOR = "collector";
    public String collector;
    JSONArray USER = null;
    JSONObject jObj = null;

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

    }

    @Override
    protected Void doInBackground(Void... params) {
        // Checks on the server if collector is registered
        try {
            jObj = ServerUtilities.UserRegistered(context, collector);
            return null;
        } finally {
            return null;
        }
    }

    @Override
    protected void onPostExecute(Void result) {
        try {

            String success = jObj.getString(TAG_SUCCESS);
            Log.d(TAG_COLLECTOR, "Final Info: " + success);

            //This if sees if user correct
            if (Objects.equals(success, "1")){
                //GOOD! THE COLLECTOR EXISTS!!
            }

        } catch (JSONException e) {
            e.printStackTrace();
            Log.d(TAG_COLLECTOR, "JSON parsing didn't work");
        }
    }
} 

I have checked several posts, but I still havent found out the way to retrieve the boolean where I call the Asynktask, something like this :

task=new isCollectorRegistered();
task.execute();
boolean UserRegistered = task.result();

What would be the right approach? Any help would be appreciated

Alvaro
  • 1,430
  • 2
  • 23
  • 41
  • 1
    http://stackoverflow.com/questions/9458258/return-value-from-async-task-in-android – riteshtch Mar 01 '16 at 10:40
  • @ritesht93 thank you! so in fact is impossible to retrieve a value once the AsyncTask is executing because it is running a totally different thread no? – Alvaro Mar 01 '16 at 10:44
  • 1
    yes `doInBackground()` executes in a different thread, however you can pass values from `doInBackground()` to `publishProgress()` or to `onPostExecute()`(these 2 methods run on activity's UI thread and you can use them to persist your values) – riteshtch Mar 01 '16 at 10:51
  • @ritesht93 - did you check out my answer below? What do you think about the approach I use? Lemme know. O&O!. – SilSur Aug 17 '17 at 16:04

2 Answers2

1

To use AsyncTask you must subclass it. AsyncTask uses generics and varargs. The parameters are the following AsyncTask <TypeOfVarArgParams , ProgressValue , ResultValue> .

An AsyncTask is started via the execute() method.

The execute() method calls the doInBackground() and the onPostExecute() method.

TypeOfVarArgParams is passed into the doInBackground() method as input, ProgressValue is used for progress information and ResultValue must be returned from doInBackground() method and is passed to onPostExecute() as a parameter.

In your case you are passing Void to your AsyncTask : isCollectorRegistered extends AsyncTask<Void, Void, Void> so you can't get your result from the thread. please read this tutorial to a deep understand of the AsyncTask in Android

Fakher
  • 2,098
  • 3
  • 29
  • 45
1

I think the following is exactly what you were looking for, Alvaro...

NOTE: I tweaked your code to make it more sensible, but I tried to stick to as much of your original code as possible...

    public class RegisterCollector extends AsyncTask<String, Void, Boolean> {

        private static final String TAG_SUCCESS = "success";
        private static final String TAG_COLLECTOR = "collector";

        int TAG_SUCCESS1;
        String[] strArray;
        JSONArray USER = null;
        JSONObject jObj = null;
        public String collector;
        private AppCompatActivity mAct;  // Just incase you need an Activity Context inside your AsyncTask...
        private ProgressDialog progDial;

        // Pass data to the AsyncTask class via constructor -> HACK!!
        // This is a HACK because you are apparently only suppose to pass data to AsyncTask via the 'execute()' method.
        public RegisterCollector (AppCompatActivity mAct, String[] strArray) {
            this.mAct = mAct;
            this.strArray = strArray;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // AHAH!! - So we do need that Activity Context after all...*TISK* *TISK* @ Google **sigh**.
            progDial = ProgressDialog.show(mAct, "Please wait...", "Fetching the strawberries & cream", true, false);
        }

        @Override
        protected Boolean doInBackground(String... params) {
            // Checks on the server if collector is registered
            try {
                jObj = ServerUtilities.UserRegistered(context, collector);
                return true;  // return whatever Boolean you require here.
            } finally {
                return false;  // return whatever Boolean you require here.
            }
        }

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

                String success = jObj.getString(TAG_SUCCESS);
                Log.d(TAG_COLLECTOR, "Final Info: " + success);

                // This 'if' block checks if the user is correct...
                if (Objects.equals(success, "1")){
                    //GOOD! THE COLLECTOR EXISTS!!
                }

                // You can then also use the Boolean result here if you need to...
                if (result) {
                    // GOOD! THE COLLECTOR EXISTS!!
                } else {
                    // Oh my --> We need to try again!! :(
                }

            } catch (JSONException e) {
                e.printStackTrace();
                Log.d(TAG_COLLECTOR, "JSON parsing didn't work");
                Toast.makeText(mAct, "JSON parsing FAILED - Please try again.", Toast.LENGTH_LONG).show();
            }
        }
    } 


...then if you want to use the generated Boolean data outside the AsyncTask class try the following:
.

    RegisterCollector regisColctr = new RegisterCollector((AppCompatActivity) this, String[] myStrArry);
    AsyncTask<String, Void, Boolean> exeRegisColctr = regisColctr.execute("");
    Boolean isColctrRegistered = false;
    try {
        isColctrRegistered = exeRegisColctr.get();  // This is how you FINALLY 'get' the Boolean data outside the AsyncTask...-> VERY IMPORTANT!!
    } catch (InterruptedException in) {
        in.printStackTrace();
    } catch (ExecutionException ex) {
        ex.printStackTrace();
    }

    if (isColctrRegistered) {
        // Do whatever tasks you need to do here based on the positive (i.e. 'true') AsyncTask Bool result...
    } else {
        // Do whatever tasks you need to do here based on the negative (i.e. 'false') AsyncTask Bool result...
    }


There you go - I think this is what you were looking for (originally). I always use this approach whenever I need Async data externally, and it has yet to fail me...
.

SilSur
  • 495
  • 1
  • 6
  • 21