Ошибка "привести к тупику" при выполнении определенного действия несколько раз

Я тестирую свое приложение на устройстве, и после выполнения определенной операции 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();
Другие вопросы по тегам