0

Here is my scenario:

I have a login form which has a member key field, once the user enters this key I communicate with server to authenticate. There are two more fields namely key and type I add up these in a JSON object and send that across to the server.

Now due to a request I also have to send across the GCM token along with this login information in one call. On submit button click I start the following async task

My do in Background method looks like this:

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

            if (checkPlayServices()) {
                   Intent intent = new Intent(LoginActivity.this, GcmRegistrationIntentService.class);
                   startService(intent);
            }
/***// I want to wait here and fetch the GCM token value//***/

            try {
                JSONObject jObj;
                jObj = new JSONObject();

                jObj.put("aes_key", UtilityClass.getencryptkey());
                jObj.put("client_id", key);
                jObj.put("type", "Android");
                // jObj.put("device_token", ); <--- Need to wait for this value


                System.out.println(jObj);
                String authenticateResp = authenticate(jObj);
                System.out.println("Response is: " + authenticateResp);

                JSONObject jResp = new JSONObject(authenticateResp);
                String success = jResp.getString("success");


                if (success.equalsIgnoreCase("True")) {

                    sessionManager.createLoginSession(key);
                    return "granted";

                } else {
                    return jResp.getString("msg");

                }
            } catch (Exception e) {
                e.printStackTrace();
                return "Something went wrong, we are working to fix this, please try again after sometime";
            }
        }

        public String authenticate(JSONObject jObject) {
            return UniversalNetworkConnection.postJSONObject(getResources().getString(R.string.authentication_url), jObject);
        }

So first I start with starting the intent service - which has a registered local broadcast determining that the service has finished, I get the handler to this in onCreate of the particular activity.

 mRegistrationBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                Log.d("Login Act", "GCM done");
            }
        };

I want to wait in the middle of the doInBackground till I receive the local broadcast from my intent service. So that I can add up the value to my JSON object. It is necessary for me to do this in an Async task because I have to update the UI with relevant messages of authentication success or false. Otherwise I could have migrated all my logic to the intent service - which would be a lot couples and which is not a good design.

User3
  • 2,465
  • 8
  • 41
  • 84

3 Answers3

2

Move all your logic to onReceive of that broadcast receiver. Declare that receiver as an inner class of your activity and then you can manipulate UI within it.

So the steps after user click are:

  • Start that Intent Service.
  • Send an broad cast in that service when you are done.
  • Send your JSON object in onReceive method.

Note: if you want to send that JSON in background thread, you could simply define an thread inside onReceive and do the work.

frogatto
  • 28,539
  • 11
  • 83
  • 129
  • I am of the opinion that this would be the best solution, however it means refactoring a lot of code and keeping track of UI messages would be come tedious. However I still am of the opinion that I will go with this way – User3 Sep 18 '15 at 11:48
0

You cannot do another asynchronous task inside doInBackground. This answer might help you: https://stackoverflow.com/a/15657500/4676276

What you can do is, start the smaller async task first then wait for it to finish then start the main async on the onPostExecute of the first task.

Community
  • 1
  • 1
AC-OpenSource
  • 346
  • 1
  • 12
0

Try this...

Check for the key and wait

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

        if (checkPlayServices()) {
               Intent intent = new Intent(LoginActivity.this, GcmRegistrationIntentService.class);
               startService(intent);
        }
        /***// I want to wait here and fetch the GCM token value//***/

        while(key==null||key.length()==0){

            try {
                Thread.sleep(1000);
            }catch (InterruptedException e) {
                e.printStackTrace();
            }

       }

       try {
            JSONObject jObj;
            jObj = new JSONObject();

            jObj.put("aes_key", UtilityClass.getencryptkey());
            jObj.put("client_id", key);
            jObj.put("type", "Android");
       /**********************/

   }
uday
  • 1,348
  • 12
  • 27