Android &引用;“导致僵局”;多次执行某项活动时出错
我正在设备上测试我的应用程序,在执行某个活动5或6次后,该应用程序崩溃并出现错误:Android &引用;“导致僵局”;多次执行某项活动时出错,android,performance,android-account,Android,Performance,Android Account,我正在设备上测试我的应用程序,在执行某个活动5或6次后,该应用程序崩溃并出现错误:java.lang.IllegalStateException:从主线程调用该应用程序可能导致死锁 活动很简单:用户输入一个任务并单击保存。此时,我获取他们的用户名和authtoken,并向我的服务器发出POST请求。我想知道我的应用程序是否会崩溃,因为每次我都会得到用户名和authtoken 崩溃发生在下面代码的newcreatetask行 public boolean onOptionsItemSelected
java.lang.IllegalStateException:从主线程调用该应用程序可能导致死锁
活动很简单:用户输入一个任务并单击保存。此时,我获取他们的用户名和authtoken,并向我的服务器发出POST请求。我想知道我的应用程序是否会崩溃,因为每次我都会得到用户名和authtoken
崩溃发生在下面代码的newcreatetask
行
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;
}
}
公共类MyAccount{
私有静态最终字符串TAG=“MyAccount”;
私人最终账户;
私人最终会计经理;
私人最终语境;
公共MyAccount(最终上下文){
this.context=上下文;
最终账户[]账户=AccountManager.get(上下文).getAccountsByType(“com.myapp”);
account=accounts.length>0?accounts[0]:空;
manager=AccountManager.get(上下文);
}
公共字符串getPassword(){
返回帐户!=null?管理器。getPassword(帐户):null;
}
公共字符串getUsername(){
退货账户!=null?账户名称:null;
}
公共字符串getAuthToken(){
如果(帐户!=null){
AccountManagerFuture=manager.getAuthToken(帐户,“com.myapp”,false,null,null);
试一试{
Bundle result=future.getResult();
返回结果!=null?result.getString(KEY\u AUTHTOKEN):null;
}捕获(AccountSexException e){
Log.e(标记“身份验证令牌查找失败”,e);
返回null;
}捕获(IOE异常){
Log.e(标记“身份验证令牌查找失败”,e);
返回null;
}
}
其他的
返回null;
}
}
问题
这不是最好的做法吗?我的应用程序崩溃是因为我不断重复获取
帐户
和authtoken
?避免这种情况的方法是什么?请在您使用的方法的说明中注意这一点:
可以从任何线程调用此方法,但是
不得在主线程上使用AccountManagerFuture
您显然违反了这一点,因为您的MyAccount#getAuthToken()
正在访问主线程上的Future
:Bundle result=Future.getResult()代码>
我想这就是为什么你会得到这个例外
希望能有所帮助。是的,您应该致电manager.getAuthToken(…);在一个单独的线程中,AsyncTask是可以的。实际上,根据它的说法,getAuthToken
可能不需要单独的线程。让我检查一下,我将尝试将MyAccount
功能包装到一个单独的asynctask中,该任务从createTask
调用,并将发布我的进度。感谢问题不在于在UI线程上调用manager.getAuthToken
,而是在主线程上操作返回的Future
对象。请看我重新编写的答案。在代码中添加一些解释将使您的答案对未来的搜索者更有用。
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();