I want to customize the process of obtaining the authentication token from AccountManager.
AccountManager
has getAuthToken()
and getAuthTokenByFeatures()
methods, but I want to implement a customized flow, which includes switching between activities, etc...
I wanted to implement it the following way:
public AccountManagerFuture<Bundle> getAuthTokenForActiveAccount() {
GetAuthTokenForActiveAccountFuture future =
new GetAuthTokenForActiveAccountFuture(MyActivity.this);
future.start();
return future;
}
Using the following nested class in my activity:
private static class GetAuthTokenForActiveAccountFuture extends Thread implements
AccountManagerFuture<Bundle> {
private final Activity mActivity;
public GetAuthTokenForActiveAccountFuture(Activity activity) {
mActivity = activity;
// TODO: write this method
}
@Override
public void run() {
// TODO: write this method
}
@Override
public boolean cancel(boolean b) {
// TODO: write this method
return false;
}
@Override
public boolean isCancelled() {
// TODO: write this method
return false;
}
@Override
public boolean isDone() {
// TODO: write this method
return false;
}
@Override
public Bundle getResult() throws
OperationCanceledException, IOException, AuthenticatorException {
return internalGetResult(null, null);
}
@Override
public Bundle getResult(long timeout, TimeUnit timeUnit) throws
OperationCanceledException, IOException, AuthenticatorException {
return internalGetResult(timeout, timeUnit);
}
private Bundle internalGetResult(Long timeout, TimeUnit timeUnit) throws
OperationCanceledException, IOException, AuthenticatorException {
// TODO: write this method
return null;
}
}
My idea was that I could create my own AccountManagerFuture object and "unblock" its getResult()
method only after all the required steps were done (some of them include activity switching).
I got two issues here:
- I need
Activity
context for switching to other activities when necessary, but theActivity
I pass into constructor should be destroyed when I switch to other activity, but it won't because myThread
holds a reference to it... So I create a memory leak here. It seems that making the inner class non-static won't resolve this issue - the reference returned fromgetAuthTokenForActiveAccount()
will still prevent from the outerActivity
to be garbage collected. Is there any way I could achieve what I try to do without leaking the context? Thread
is eligible for garbage collection once itsrun()
method returns, right? But in my case I want this thread to stick around because it also functions asAccountManagerFuture
- it should be kept in memory until all references to it are gone. My question is this: is it enough to keep a (strong) reference toThread
for preventing it from being garbage collected? If not, how could I force thisThread
to stick around until all references are gone?