AsynTask - onPostExecute is called before doInBack

2019-09-16 01:10发布

问题:

i got a problem getting my AsyncTask to work correct. My App offers the possibility to connect with your Google Account and add and receive tasks by using the Tasks API. When the users wants to synchronize with his account, the doInBackground() method is started. Right before that, a ProgressDialog is displayed in the onPreExecute() method of the AsyncTask class.
If the synchronisation has been successfully executed, the onPostExecute() method 'should' be called fading out the ProgressDialog.
But there is problem: the onPostExecute() ethod is called before the work in the doInBackground() is finished. In doInBackground() I receive the token used for the authorization:

token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);

That's all. But right before that, the onPostExecute() is called and the ProgressDialog disappears while the token is still retrieving. The wired thing is that when I start the app and synchronizes for the first time, it works like it should. But after that the onPostExecute() method finishes before the work is completed. Does this have to do that there are requests to a server while executing

future.getResult().getString(AccountManager.KEY_AUTHTOKEN);

How can I tell the onPostExecute() method that there is still work to do?

private class SynchronizeGoogle extends AsyncTask<Void, Integer, Void> 
    {
    private final ProgressDialog dialog = new ProgressDialog(RememberMe.this);
    protected void onPreExecute() 
    {
        this.dialog.setMessage("Listen werden geladen...");
        this.dialog.show();
     }

    @Override
    protected Void doInBackground(Void... arg0) 
    {
        try 
            {
            switch(startSynchronize())
                {
                    case 0: 
                        publishProgress(0);
                        return null;
                    case 1: 
                        publishProgress(1);
                        return null;
                    case 2: 
                        publishProgress(2);
                        return null;
                }
            } 
        catch (IOException e) 
            {
                e.printStackTrace();
            }

                    synchronize();


        return null;
    }

    protected void onProgressUpdate(Integer... type)
    {
        int typeCase = type[0];
        switch(typeCase)
        {
            case 0:
                showDialog(DIALOG_INTERNET_ACCESS);
                break;
            case 1:
                showDialog(DIALOG_CREATE_ACCOUNT);
                break;
            case 2:
                showDialog(DIALOG_ACCOUNTS);
                break;

        }


    }

      protected void onPostExecute(final Void unused) 
      {


          if (this.dialog.isShowing()) 
          {
             this.dialog.dismiss();
          }

      }
}

And here my startSynchronize() and synchronize() methods:

private int startSynchronize() throws IOException
{
            googleAccountManager = new GoogleAccountManager(RememberMe.this);
    Account[] accounts = googleAccountManager.getAccounts();

    if(checkAccess.internetAccess() == false)
    {
        return 0;
    }
    if(accounts.length == 0)
        {
            return 1;
        }
    else
        {
            if(accounts.length == 1)
            {
                account = accounts[0];

            }
            else
            {
                return 2;
            }
        }

    return -1;
}   

private void synchronize()
{       
myPrefs = this.getSharedPreferences("myPrefs", MODE_PRIVATE);

String oldToken = myPrefs.getString(MY_TOKEN, "");

    if(oldToken.length() > 0)
        {
                            // invalidate old token to be able to receive a new one
            googleAccountManager.invalidateAuthToken(oldToken); 

        }

    googleAccountManager.manager.getAuthToken(account, AUTH_TOKEN_TYPE, true, new AccountManagerCallback<Bundle>() 
            {
            public void run(AccountManagerFuture<Bundle> future) 
                    {
                        try 
                            {

                        token = future.getResult().getString(AccountManager.KEY_AUTHTOKEN);

                                         prefsEditor.putString(MY_TOKEN, token);
                                prefsEditor.commit();

                    useTasksAPI(token);

                            } 
                    catch (OperationCanceledException e) 
                            {
                            //...
                            } 
                    catch (Exception e) 
                            {
                            //...
                            }
                    }
          }, null);


}

In the Optionsmenu i start it like this

new SynchronizeGoogle().execute();

Thanks everybody for your help

回答1:

If I do not misunderstand your question, you're wrong with getResult() method usage.

When getResult() called by anywhere in your code, AsyncTask does not wait until finish. So you need to do your process in onPostExecute method.

I recommend you this question&answer. I hope, it's gonna help you.