Ошибка "привести к тупику" при выполнении определенного действия несколько раз
Я тестирую свое приложение на устройстве, и после выполнения определенной операции 5 или 6 раз приложение вылетает с ошибкой: java.lang.IllegalStateException: calling this from your main thread can lead to deadlock
Действие простое: пользователь ставит задачу и нажимает сохранить. В это время я получаю их имя пользователя и authtoken и отправляю запрос POST на мой сервер. Интересно, происходит ли сбой моего приложения, потому что каждый раз, когда я получаю имя пользователя и авторизацию.
Сбой происходит в приведенном ниже коде в строке 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
несколько раз? Как избежать этого?
2 ответа
Обратите внимание на это утверждение в описании метода 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();