0

我想使用此代碼:方法的AsyncTask的Android OAuth2Client

public static Token getAccessToken(OAuth2Config oauthDetails) { 
    HttpPost post = new HttpPost(oauthDetails.getTokenEndPointUrl()); 
    String clientId = oauthDetails.getClientId(); 
    String clientSecret = oauthDetails.getClientSecret(); 
    String scope = oauthDetails.getScope(); 
    List<BasicNameValuePair> parametersBody = new ArrayList<BasicNameValuePair>(); 
    parametersBody.add(new BasicNameValuePair(OAuthConstants.GRANT_TYPE, 
      oauthDetails.getGrantType())); 
    parametersBody.add(new BasicNameValuePair(OAuthConstants.USERNAME, 
      oauthDetails.getUsername())); 
    parametersBody.add(new BasicNameValuePair(OAuthConstants.PASSWORD, 
      oauthDetails.getPassword())); 
    if (isValid(clientId)) { 
     parametersBody.add(new BasicNameValuePair(OAuthConstants.CLIENT_ID, 
       clientId)); 
    } 
    if (isValid(clientSecret)) { 
     parametersBody.add(new BasicNameValuePair(
       OAuthConstants.CLIENT_SECRET, clientSecret)); 
    } 
    if (isValid(scope)) { 
     parametersBody.add(new BasicNameValuePair(OAuthConstants.SCOPE, 
       scope)); 
    } 
    DefaultHttpClient client = new DefaultHttpClient(); 
    HttpResponse response = null; 
    Token accessToken = null; 
    try { 
     post.setEntity(new UrlEncodedFormEntity(parametersBody, HTTP.UTF_8)); 
     response = client.execute(post); 
     int code = response.getStatusLine().getStatusCode(); 
     if (code >= 400) { 
      Log.d(TAG, "Authorization server expects Basic authentication"); 
       // Add Basic Authorization header 
      post.addHeader(
        OAuthConstants.AUTHORIZATION, 
        getBasicAuthorizationHeader(oauthDetails.getUsername(), 
          oauthDetails.getPassword())); 
      Log.d(TAG, "Retry with login credentials"); 
      try { 
       response.getEntity().consumeContent(); 
      } catch (IOException e) { 
        // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
      response = client.execute(post); 
      code = response.getStatusLine().getStatusCode(); 
      if (code >= 400) { 
       Log.d(TAG, "Retry with client credentials"); 
       post.removeHeaders(OAuthConstants.AUTHORIZATION); 
       post.addHeader(
         OAuthConstants.AUTHORIZATION, 
         getBasicAuthorizationHeader(
           oauthDetails.getClientId(), 
           oauthDetails.getClientSecret())); 
       try { 
        response.getEntity().consumeContent(); 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
       response = client.execute(post); 
       code = response.getStatusLine().getStatusCode(); 
       if (code >= 400) { 
        throw new RuntimeException(
          "Could not retrieve access token for user: " 
            + oauthDetails.getUsername()); 
       } 
      } 
     } 
     Map map = handleResponse(response); 
     accessToken = new Token(Long.valueOf((Integer) map.get(OAuthConstants.EXPIRES_IN)), (String) map.get(OAuthConstants.TOKEN_TYPE), (String) map.get(OAuthConstants.REFRESH_TOKEN), (String) map.get(OAuthConstants.ACCESS_TOKEN)); 
    } catch (ClientProtocolException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
      // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    return accessToken; 
} 

是,我用我的Android應用程序的OAuth2Client的一部分。 我收到此錯誤:

android.os.NetworkOnMainThreadException 

和我讀,我應該使用的AsyncTask,但我不知道如何將這種方法轉換成的AsyncTask。

我會提供一些幫助。

感謝

回答

0

首先你需要一個片段來包裝你asynctask因此,如果裝置使你沒有創建多個請求和泄漏這一點。此外,您還需要聽衆(GetAccessTokenCallbacks)通知您的活動已完成並返回結果。

public class GetAccessTokenFragment extends Fragment { 


OAuth2Config mOauthDetails; 

static interface GetAccessTokenCallbacks { 
    void onPostExecute(Token token); 
} 

private GetAccessTokenCallbacks mCallbacks; 
private AccessTokenTask mTask; 


@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 
    mCallbacks = (GetAccessTokenCallbacks) activity; 
} 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setRetainInstance(true); 
    // you must do it as follow 
    // first create new instance 
    // mOauthDetails = new OAuth2Config(....) 
    // then use the values of MainActivity.this.mOauthDetails to initialize it 


    mTask = new AccessTokenTask(); 
    mTask.execute(); 

} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mCallbacks = null; 
} 



private class AccessTokenTask extends AsyncTask<Void, Void, Token> { 

    @Override 
    protected Token doInBackground(Void... param) { 

    Token token = TheClassOfThisFunction.getAccessToken(mOauthDetails); 
    return token; 
    } 

    @Override 
    protected void onPostExecute(Token token) { 
    if (mCallbacks != null) { 
     mCallbacks.onPostExecute(token[0]); 
    } 
    } 
} 
} 

,並在您MainActivity必須實現GetAccessTokenFragment.GetAccessTokenCallbacks和創建GetAccessTokenFragment

public class MainActivity extends FragmentActivity implements GetAccessTokenFragment.GetAccessTokenCallbacks { 

     public OAuth2Config mOauthDetails; 

     private static final String TAG_GetAccessTokenFragment = "GetAccessToken"; 

     private GetAccessTokenFragment mGetAccessTokenFragment; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 


     // Initialize mOauthDetails here 


     FragmentManager fm = getSupportFragmentManager(); 
     mGetAccessTokenFragment = (GetAccessTokenFragment) fm.findFragmentByTag(TAG_GetAccessTokenFragment); 

     if (mGetAccessTokenFragment == null) { 
      mGetAccessTokenFragment = new GetAccessTokenFragment(); 
      fm.beginTransaction().add(mGetAccessTokenFragment, TAG_GetAccessTokenFragment).commit(); 
     } 

     } 

     @Override 
     public void onPostExecute(Token token) { 
      //you got your token here 
     } 
    } 

似乎的OAuthConfig被稱爲在以下幾點:

public class OAuth2Client { 
private final String username; 
private final String password; 
private final String clientId; 
private final String clientSecret; 
private final String site; 
public OAuth2Client(String username, String password, String clientId, String clientSecret, String site) { 
    this.username = username; 
    this.password = password; 
    this.clientId = clientId; 
    this.clientSecret = clientSecret; 
    this.site = site; 
} 
public String getUsername() { 
    return username; 
} 
public String getPassword() { 
    return password; 
} 
public String getClientId() { 
    return clientId; 
} 
public String getClientSecret() { 
    return clientSecret; 
} 
public String getSite() { 
    return site; 
} 
public Token getAccessToken() { 
    OAuth2Config oauthConfig = new OAuth2Config.OAuth2ConfigBuilder(username, password, clientId, clientSecret, site) 
      .grantType("password").build(); 
    return OAuthUtils.getAccessToken(oauthConfig); 
} 

}

+0

我的應用程序只有2與片段集裝箱活動,基本上我的應用程序處理片段所有的時間。當用戶按登錄按鈕時,會出現一個名爲LogInFragment的片段,用戶將輸入用戶名和密碼。當用戶確認用戶名和密碼時,它會調用一個Dialog Fragment,它只顯示Login in ...以及所有日誌進行完成的地方。 – Bozow 2014-10-24 06:30:21

+0

我想我明白了,我現在會測試它。基本上我必須得到accessToken的方法不需要是asyncTask,但我應該在AsyncTask中執行該方法。我明白了嗎? – Bozow 2014-10-24 06:46:54

+0

準確地說,我的代碼只是爲你做的,我把'getAccessToken'放在'doInBackground'中,並且因爲'doInBackground'運行在其他線程(工作線程)上,你將得到該異常。因爲用戶可以旋轉你的設備,這會導致對'getAccessToken'的另一個調用,我認爲這是不必要的,我把AsyncTask放到一個保留的片段中只需要一次。 – mmlooloo 2014-10-24 06:56:02