问题
I am trying to get the authToken
for an account but getting this error:
java.lang.IllegalStateException: calling this from your main thread can lead to deadlock
This is how I'm getting the AuthToken:
public class MyAccount {
private final Account account;
private final AccountManager manager;
private final Context context;
public MyAccount (Context context) {
this.context = context;
final Account[] accounts = AccountManager.get(context).getAccountsByType("com.myapp");
account = accounts.length > 0 ? accounts[0] : null;
manager = AccountManager.get(context);
}
public String getAuthToken() {
@SuppressWarnings("deprecation")
AccountManagerFuture<Bundle> future = manager.getAuthToken(account,"com.myapp", false, null, null);
try {
//GETTING EXCEPTION HERE
Bundle result = future.getResult();
return result != null ? result.getString(KEY_AUTHTOKEN) : null;
} catch (AccountsException e) {
Log.e(TAG, "Auth token lookup failed", e);
return null;
} catch (IOException e) {
Log.e(TAG, "Auth token lookup failed", e);
return null;
}
}
}
I'm calling this from my MainActivity like this:
MyAccount account = new MyAccount(getApplicationContext());
String authtoken = account.getAuthToken());
Question
How can I call MyAccount
to get the authToken and get rid of the exception?
回答1:
USe an AsyncTask so that this work may be completed in a background thread (doInBackground)
private class FooTask extends AsyncTask<Void, Void, String>{
/**
* Override this method to perform a computation on a background thread. The
* specified parameters are the parameters passed to {@link #execute}
* by the caller of this task.
*
* This method can call {@link #publishProgress} to publish updates
* on the UI thread.
*
* @param params The parameters of the task.
*
* @return A result, defined by the subclass of this task.
*
* @see #onPreExecute()
* @see #onPostExecute
* @see #publishProgress
*/
@Override
protected String doInBackground(Void... params) {
MyAccount account = new MyAccount(getApplicationContext());
String authtoken = account.getAuthToken());
return authtoken;
}
/**
* <p>Runs on the UI thread after {@link #doInBackground}. The
* specified result is the value returned by {@link #doInBackground}.</p>
*
* <p>This method won't be invoked if the task was cancelled.</p>
*
* @param result The result of the operation computed by {@link #doInBackground}.
*
* @see #onPreExecute
* @see #doInBackground
* @see #onCancelled(Object)
*/
@Override
protected void onPostExecute(String token) {
if (token != null){
//use token here
}
}
}
Usage : new FooTask().execute();
回答2:
from
"Calling this from your main thread can lead to deadlock and/or ANRs while getting accesToken" from GoogleAuthUtil(Google Plus integration in Android)
Try it with an AsyncTask like this:
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>() {
@Override
protected String doInBackground(Void... params) {
String token = null;
try {
token = GoogleAuthUtil.getToken(
MainActivity.this,
mPlusClient.getAccountName(),
"oauth2:" + SCOPES);
} catch (IOException transientEx) {
// Network or server error, try later
Log.e(TAG, transientEx.toString());
} catch (UserRecoverableAuthException e) {
// Recover (with e.getIntent())
Log.e(TAG, e.toString());
Intent recover = e.getIntent();
startActivityForResult(recover, REQUEST_CODE_TOKEN_AUTH);
} catch (GoogleAuthException authEx) {
// The call is not ever expected to succeed
// assuming you have already verified that
// Google Play services is installed.
Log.e(TAG, authEx.toString());
}
return token;
}
@Override
protected void onPostExecute(String token) {
Log.i(TAG, "Access token retrieved:" + token);
}
来源:https://stackoverflow.com/questions/20749044/how-to-get-rid-of-java-lang-illegalstateexception-while-trying-to-getauthtoken-f