2014-01-23 45 views
1

我測試我的應用程序的設備上,並做一定的活動5〜6倍,應用程序崩潰,出現錯誤後,當錯誤:java.lang.IllegalStateException: calling this from your main thread can lead to deadlock「導致死鎖」做一定的活動多次

活動是簡單:用戶放入任務並單擊保存。此時,我獲得了他們的用戶名和authtoken,並向我的服務器發出POST請求。我想知道我的應用程序是否因爲每次獲取用戶名和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; 
    } 
} 

問題

難道這不是最好的實踐?我的應用程序崩潰了,因爲我反覆收到accountauthtoken?什麼是避免這種情況的方法?

+0

問題不在於在UI線程中調用'manager.getAuthToken',而是在主線程上操作返回的'Future'對象。請看我重寫的答案。 – kiruwka

回答

1

請注意在getAuthToken方法說明這種說法你使用:

This method may be called from any thread, but the returned AccountManagerFuture must not be used on the main thread.

你顯然違反了這一點,因爲你MyAccount#getAuthToken()是在主線程訪問FutureBundle result = future.getResult();

我認爲這就是爲什麼你會得到例外。

希望有所幫助。

+0

是的,你應該調用manager.getAuthToken(...);在一個單獨的線程中,AsyncTask很好。 – kiruwka

+0

不錯,實際上根據[this](http://developer.android.com/reference/android/accounts/AccountManager.html#blockingGetAuthToken%28android.accounts.Account,%20java.lang.String,%20boolean%29) 'getAuthToken'可能不需要單獨的線程。讓我檢查 – kiruwka

+0

太棒了!感謝它 – Anthony

0
 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(); 
+0

向你的代碼添加一些解釋會讓你對未來的搜索者有更多幫助。 – Brody