Fix bug causing Login to hang when called from another AsyncTask

This commit is contained in:
YuviPanda 2012-10-17 21:01:04 +05:30
parent 76fc431532
commit 388eed5aee
3 changed files with 72 additions and 80 deletions

View file

@ -85,6 +85,8 @@ public class ShareActivity extends AuthenticatedActivity {
descEdit = (EditText)findViewById(R.id.descEdit);
uploadButton = (Button)findViewById(R.id.uploadButton);
requestAuthToken();
}
@Override

View file

@ -19,8 +19,7 @@ public class AuthenticatedActivity extends Activity {
}
private class GetAuthCookieTask extends AsyncTask<String, String, String> {
private class GetAuthCookieTask extends AsyncTask<Void, String, String> {
private Account account;
private AccountManager accountManager;
public GetAuthCookieTask(Account account, AccountManager accountManager) {
@ -39,7 +38,7 @@ public class AuthenticatedActivity extends Activity {
}
@Override
protected String doInBackground(String... params) {
protected String doInBackground(Void... params) {
try {
return accountManager.blockingGetAuthToken(account, "", false);
} catch (OperationCanceledException e) {
@ -53,87 +52,74 @@ public class AuthenticatedActivity extends Activity {
return null;
}
}
}
// private class onTokenAcquired implements AccountManagerCallback<Bundle> {
//
// @Override
// public void run(AccountManagerFuture<Bundle> result) {
// Bundle bundle;
// try {
// bundle = result.getResult();
// } catch (OperationCanceledException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// throw new RuntimeException(e);
// } catch (AuthenticatorException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// throw new RuntimeException(e);
// } catch (IOException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// throw new RuntimeException(e);
// }
// Log.d("Commons", "Token Found!");
// if(bundle.containsKey(AccountManager.KEY_AUTHTOKEN)) {
// String authCookie = bundle.getString(AccountManager.KEY_AUTHTOKEN);
// onAuthCookieAcquired(authCookie);
// } else {
// if(bundle.containsKey(AccountManager.KEY_INTENT)) {
// Intent launchIntent = (Intent) bundle.get(AccountManager.KEY_INTENT);
// startActivityForResult(launchIntent, 0);
// } else {
//
// }
// }
//
// }
// }
//
//
// @Override
// protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// super.onActivityResult(requestCode, resultCode, data);
// Log.d("Commons", "Result of the loginactivity!");
// if(resultCode == Activity.RESULT_OK) {
// requestAuthToken();
// }
// }
//
// private void requestAuthToken() {
// AccountManager accountManager = AccountManager.get(this);
// Account[] allAccounts =accountManager.getAccountsByType(accountType);
// if(allAccounts.length == 0) {
// Log.d("Commons", "No accounts yet!");
// // No Commons Accounts yet!
// accountManager.addAccount(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE, "", null, null, this, new onTokenAcquired(), null);
// return;
// }
//
// Log.d("Commons", "Accounts found!");
// // For now - always pick the first account
// Account curAccount = allAccounts[0];
// Bundle cookieOptions = new Bundle();
// accountManager.getAuthToken(curAccount, "", cookieOptions, this, new onTokenAcquired(), null);
// }
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AccountManager accountManager = AccountManager.get(this);
Account[] allAccounts =accountManager.getAccountsByType(accountType);
if(allAccounts.length == 0) {
// No Commons Accounts yet!
accountManager.addAccount(WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE, "", null, null, this, null, null);
return;
private class AddAccountTask extends AsyncTask<Void, String, String> {
private AccountManager accountManager;
public AddAccountTask(AccountManager accountManager) {
this.accountManager = accountManager;
}
// For now - always pick the first account
Account curAccount = allAccounts[0];
GetAuthCookieTask task = new GetAuthCookieTask(curAccount, accountManager);
task.execute("");
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result != null) {
Account[] allAccounts =accountManager.getAccountsByType(accountType);
Account curAccount = allAccounts[0];
GetAuthCookieTask getCookieTask = new GetAuthCookieTask(curAccount, accountManager);
getCookieTask.execute();
} else {
onAuthFailure();
}
}
@Override
protected String doInBackground(Void... params) {
AccountManagerFuture<Bundle> resultFuture = accountManager.addAccount(accountType, null, null, null, AuthenticatedActivity.this, null, null);
Bundle result;
try {
result = resultFuture.getResult();
} catch (OperationCanceledException e) {
e.printStackTrace();
return null;
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
if(result.containsKey(AccountManager.KEY_ACCOUNT_NAME)) {
return result.getString(AccountManager.KEY_ACCOUNT_NAME);
} else {
return null;
}
}
}
protected void requestAuthToken() {
AccountManager accountManager = AccountManager.get(this);
Account[] allAccounts =accountManager.getAccountsByType(accountType);
Account curAccount = null;
if(allAccounts.length == 0) {
AddAccountTask addAccountTask = new AddAccountTask(accountManager);
// This AsyncTask blocks until the Login Activity returns
// And since in Android 4.x+ only one background thread runs all AsyncTasks
// And since LoginActivity can't return until it's own AsyncTask (that does the login)
// returns, we have a deadlock!
// Fixed by explicitly asking this to be executed in parallel
// See: https://groups.google.com/forum/?fromgroups=#!topic/android-developers/8M0RTFfO7-M
addAccountTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
curAccount = allAccounts[0];
GetAuthCookieTask task = new GetAuthCookieTask(curAccount, accountManager);
task.execute();
}
}
protected void onAuthCookieAcquired(String authCookie) {
}

View file

@ -17,6 +17,7 @@ import android.accounts.AccountAuthenticatorResponse;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.ProgressDialog;
import android.util.Log;
import android.view.*;
import android.widget.Button;
import android.widget.EditText;
@ -43,8 +44,9 @@ public class LoginActivity extends AccountAuthenticatorActivity {
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.d("Commons", "Login done!");
if (result.equals("Success")) {
dialog.cancel();
dialog.dismiss();
Toast successToast = Toast.makeText(context, R.string.login_success, Toast.LENGTH_SHORT);
successToast.show();
Account account = new Account(username, WikiAccountAuthenticator.COMMONS_ACCOUNT_TYPE);
@ -112,6 +114,8 @@ public class LoginActivity extends AccountAuthenticatorActivity {
String username = usernameEdit.getText().toString();
String password = passwordEdit.getText().toString();
Log.d("Commons", "Login to start!");
LoginTask task = new LoginTask(that);
task.execute(username, password);
}