AsynTask - onPostExecute вызывается перед doInBackground - PullRequest
0 голосов
/ 28 января 2012

У меня проблема с тем, чтобы мой AsyncTask работал правильно.Мое приложение предлагает возможность подключиться к вашей учетной записи Google и добавлять и получать задачи с помощью API задач.Когда пользователь хочет синхронизироваться с его учетной записью, запускается метод doInBackground().Непосредственно перед этим в методе onPreExecute() класса AsyncTask отображается ProgressDialog.
Если синхронизация была успешно выполнена, метод onPostExecute() должен быть вызван для затухания ProgressDialog.
Но есть проблема: метод onPostExecute() вызывается до завершения работы в doInBackground()doInBackground() я получаю токен, используемый для авторизации:

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

Вот и все.Но прямо перед этим вызывается onPostExecute(), а ProgressDialog исчезает, пока токен все еще восстанавливается.Дело в том, что когда я запускаю приложение и синхронизируюсь в первый раз, оно работает так, как должно.Но после этого метод onPostExecute() заканчивается до завершения работы.Должно ли это быть связано с тем, что при выполнении

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

существуют запросы к серверу. Как я могу сказать методу onPostExecute(), что работа еще не завершена?

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();
          }

      }
}

А вот и мои методы startSynchronize () и synchronize ():

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);


}

В меню опций я запускаю это так

new SynchronizeGoogle().execute();

Спасибо всем заваша помощь

1 Ответ

3 голосов
/ 28 января 2012

Если я не неправильно понял ваш вопрос, вы ошибаетесь при использовании метода getResult().

Когда getResult() вызывается в любом месте вашего кода, AsyncTask не ожидает завершения. Так что вам нужно сделать ваш процесс в методе onPostExecute.

Я рекомендую вам этот вопрос и ответ . Надеюсь, это тебе поможет.

...