我正在设备上测试我的应用程序,在进行一定的活动5或6次之后,应用程序崩溃了: java.lang.IllegalStateException: calling this from your main thread can lead to deadlock
活动很简单:用户可以完成任务,然后单击保存。目前,我获得了他们的用户名和Authtoken,并向我的服务器提出了发布请求。我想知道我的应用程序是否崩溃了,因为每次我都会获得用户名和Authtoken。
崩溃在以下代码中发生在new CreateTask
线上。
public boolean onOptionsItemSelected(MenuItem menuItem) {
if (menuItem.getTitle().toString().equalsIgnoreCase("save")) {
new CreateTask(this,taskName.getText().toString(), getMyAccount().getUsername(), getMyAccount().getAuthToken()).execute();
return true;
}
return true
}
getMyAccount()
的代码如下:
private MyAccount getMyAccount() {
MyAccount myAccount = new MyAccount(getApplicationContext());
return myAccount;
}
最后,MyAccount
类看起来如下:
public class MyAccount {
private static final String TAG = "MyAccount";
private final Account account;
private final AccountManager manager;
private final Context context;
public MyAccount(final 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 getPassword() {
return account!=null? manager.getPassword(account): null;
}
public String getUsername() {
return account!=null? account.name: null;
}
public String getAuthToken() {
if (account != null) {
AccountManagerFuture<Bundle> future = manager.getAuthToken(account,"com.myapp", false, null, null);
try {
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;
}
}
else
return null;
}
}
问题
这不是最好的做法吗?我的应用程序崩溃了,因为我不断重复获得account
和authtoken
?避免这种情况的方法是什么?
请在您使用的getauthtoken方法的描述中记录此语句:
此方法可以从任何线程调用,但是返回 不得在主线程上使用AccountManagerFuture。
您显然违反了这一点,因为您的MyAccount#getAuthToken()
正在访问主线程上的Future
:Bundle result = future.getResult();
我认为这就是为什么您会得到异常。
希望会有所帮助。
Thread CrearEventoHilo = new Thread(){
public void run(){
//do something that retrun "Calling this from your main thread can lead to deadlock"
}
};
CrearEventoHilo.start();
CrearEventoHilo.interrupt();