AsynTask - onPostExecute is called before doInBackground

时光毁灭记忆、已成空白 提交于 2019-12-12 05:14:20

问题


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.



来源:https://stackoverflow.com/questions/9040090/asyntask-onpostexecute-is-called-before-doinbackground

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!