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
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 inonPostExecute
method.I recommend you this question&answer. I hope, it's gonna help you.