के साथ पुराने अनुरोध को पुनः प्रयास करने से पहले पुनः प्रयास करने पर नया टोकन प्राप्त करना मेरे पास वॉली का उपयोग करके लागू एक सरल प्रमाणीकरण प्रणाली है। यह इस प्रकार है: लॉगिन पर सर्वर से टोकन प्राप्त करें -> एक घंटे बाद, यह टोकन समाप्त हो जाता है -> जब यह समाप्त हो जाता है, तो हम उसे एक असफल एपीआई कॉल पर पाएंगे, इसलिए हमें (पुनः प्रयास करने) -> लाने चाहिए जब नया कॉल विफल रहता है तो नया टोकन और फिर -> मूल कॉल को पुनः प्रयास करें।वॉली
मैंने इसे कार्यान्वित किया है, और टोकन सफलतापूर्वक लौट रहा है, लेकिन क्योंकि मुझे लगता है कि मैं वॉली RequestQueue के साथ कुछ गलत कर रहा हूं, मूल अनुरोध नए और वैध टोकन का उपयोग करने में सक्षम होने से पहले इसके सभी पुनः प्रयासों का उपयोग करता है । कृपया निम्नलिखित कोड देखें:
public class GeneralAPICall extends Request<JSONObject> {
public static String LOG_TAG = GeneralAPICall.class.getSimpleName();
SessionManager sessionManager; //instance of sessionManager needed to get user's credentials
private Response.Listener<JSONObject> listener; //the response listener used to deliver the response
private Map<String, String> headers = new HashMap<>(); //the headers used to authenticate
private Map<String, String> params; //the params to pass with API call, can be null
public GeneralAPICall(int method, String url, Map<String, String> params, Context context, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
sessionManager = new SessionManager(context); //instantiate
HashMap<String, String> credentials = sessionManager.getUserDetails(); //get the user's credentials for authentication
this.listener = responseListener;
this.params = params;
//encode the user's username and token
String loginEncoded = new String(Base64.encode((credentials.get(Constants.SessionManagerConstants.KEY_USERNAME)
+ Constants.APIConstants.Characters.CHAR_COLON
+ credentials.get(Constants.SessionManagerConstants.KEY_TOKEN)).getBytes(), Base64.NO_WRAP));
Log.v(LOG_TAG, loginEncoded); //TODO: remove
this.headers.put(Constants.APIConstants.BasicAuth.AUTHORIZATION, Constants.APIConstants.BasicAuth.BASIC + loginEncoded); //set the encoded information as the header
setRetryPolicy(new TokenRetryPolicy(context)); //**THE RETRY POLICY**
}
पुन: प्रयास करें नीति मैं सेट डिफ़ॉल्ट के रूप में परिभाषित किया गया है, लेकिन मैं इस तरह के रूप में अपने स्वयं के पुन: प्रयास करें विधि को लागू:
@Override
public void retry(VolleyError error) throws VolleyError {
Log.v(LOG_TAG, "Initiating a retry");
mCurrentRetryCount++; //increment our retry count
mCurrentTimeoutMs += (mCurrentTimeoutMs * mBackoffMultiplier);
if (error instanceof AuthFailureError) { //we got a 401, and need a new token
Log.v(LOG_TAG, "AuthFailureError found!");
VolleyUser.refreshTokenTask(context, this); //**GET A NEW TOKEN**
}
if (!hasAttemptRemaining()) {
Log.v(LOG_TAG, "No attempt remaining, ERROR");
throw error;
}
}
ताज़ा टोकन काम के लिए एक RefreshAPICall
को परिभाषित करता हैpublic static void refreshTokenTask(Context context, IRefreshTokenReturn listener) {
Log.v(LOG_TAG, "refresh token task called");
final IRefreshTokenReturn callBack = listener;
RefreshAPICall request = new RefreshAPICall(Request.Method.GET, Constants.APIConstants.URL.GET_TOKEN_URL, context, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
try {
String token = response.getString(Constants.APIConstants.Returns.RETURN_TOKEN);
Log.v(LOG_TAG, "Token from return is: " + token);
callBack.onTokenRefreshComplete(token);
} catch (JSONException e) {
callBack.onTokenRefreshComplete(null); //TODO: log this
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Log.v(LOG_TAG, "Error with RETRY : " + error.toString());
}
});
VolleySingleton.getInstance(context).addToRequestQueue(request);
}
हमारे RefreshAPICall परिभाषा:
public RefreshAPICall(int method, String url, Context context, Response.Listener<JSONObject> responseListener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
sessionManager = new SessionManager(context); //instantiate
HashMap<String, String> credentials = sessionManager.getRefreshUserDetails(); //get the user's credentials for authentication
this.listener = responseListener;
//encode the user's username and token
String loginEncoded = new String(Base64.encode((credentials.get(Constants.SessionManagerConstants.KEY_USERNAME)
+ Constants.APIConstants.Characters.CHAR_COLON
+ credentials.get(Constants.SessionManagerConstants.KEY_PASSWORD)).getBytes(), Base64.NO_WRAP));
this.headers.put(Constants.APIConstants.BasicAuth.AUTHORIZATION, Constants.APIConstants.BasicAuth.BASIC + loginEncoded); //set the encoded information as the header
setTag(Constants.VolleyConstants.RETRY_TAG); //mark the retry calls with a tag so we can delete any others once we get a new token
setPriority(Priority.IMMEDIATE); //set priority as immediate because this needs to be done before anything else
//debug lines
Log.v(LOG_TAG, "RefreshAPICall made with " + credentials.get(Constants.SessionManagerConstants.KEY_USERNAME) + " " +
credentials.get(Constants.SessionManagerConstants.KEY_PASSWORD));
Log.v(LOG_TAG, "Priority set on refresh call is " + getPriority());
Log.v(LOG_TAG, "Tag for Call is " + getTag());
}
मैंने इस अनुरोध की प्राथमिकता को उच्च के रूप में सेट किया है ताकि यह असफल होने से पहले ट्रिगर हो जाए, इसलिए एक बार जब हम टोकन प्राप्त करते हैं तो मूल कॉल वैध टोकन के साथ आग लग सकता है।
अंत में, प्रतिक्रिया पर मैं फिर से प्रयास करें टैग के साथ किसी भी अन्य कार्यों (मामले में एक से अधिक API कॉल विफल रही है और कई पुन: प्रयास करें कॉल किए, हम नए टोकन कई बार अधिलेखित करने के लिए नहीं करना चाहते हैं) को हटा
@Override
public void onTokenRefreshComplete(String token) {
VolleySingleton.getInstance(context).getRequestQueue().cancelAll(Constants.VolleyConstants.RETRY_TAG);
Log.v(LOG_TAG, "Cancelled all retry calls");
SessionManager sessionManager = new SessionManager(context);
sessionManager.setStoredToken(token);
Log.v(LOG_TAG, "Logged new token");
}
दुर्भाग्यवश, लॉगकैट मुझे दिखा रहा है कि टोकन का उपयोग करने से पहले सभी रीट्री हो रही हैं। टोकन सफलतापूर्वक वापस आ रहा है, लेकिन यह स्पष्ट है कि तत्काल प्राथमिकता उस क्रम पर कोई प्रभाव नहीं डाल रही है कि कतार कॉल को प्रेषित करती है।
अन्य कार्यों की सराहना करने से पहले मेरे रिफ्रेशैपिकॉल को कैसे सुनिश्चित किया जाए, इस पर कोई मदद की गई है। मैं सोच रहा हूं कि क्या वॉली मूल विफल कार्य के उप-कार्य के रूप में रीफ्रेशैपिकॉल को मानता है, और इसलिए यह उस मूल कार्य को अपने पुनः प्रयासों के लिए कॉल करने का प्रयास करता है जब तक कि वे बाहर नहीं होते हैं, और फिर ताज़ा करें।
LogCat (यकीन नहीं इस सुंदर लग रही बनाने के लिए कैसे):
05-05 16:12:07.145: E/Volley(1972): [137] BasicNetwork.performRequest:
Unexpected response code **401 for https://url.me/api/get_friends**
05-05 16:12:07.145: V/TokenRetryPolicy(1972): Initiating a retry
05-05 16:12:07.145: V/TokenRetryPolicy(1972): AuthFailureError found!
05-05 16:12:07.146: V/VolleyUser(1972): refresh token task called
05-05 16:12:07.146: V/RefreshAPICall(1972): RefreshAPICall made with username user_password
05-05 16:12:07.147: V/RefreshAPICall(1972): Priority set on refresh call is HIGH
05-05 16:12:07.147: V/RefreshAPICall(1972): Tag for Call is retry
05-05 16:12:07.265: E/Volley(1972): [137] BasicNetwork.performRequest: Unexpected response code **401 for https://url.me/api/get_friends**
05-05 16:12:07.265: V/TokenRetryPolicy(1972): Initiating a retry
05-05 16:12:07.265: V/TokenRetryPolicy(1972): AuthFailureError found!
05-05 16:12:07.265: V/VolleyUser(1972): refresh token task called
05-05 16:12:07.265: V/RefreshAPICall(1972): RefreshAPICall made with user user_password
05-05 16:12:07.265: V/RefreshAPICall(1972): Priority set on refresh call is HIGH
05-05 16:12:07.265: V/RefreshAPICall(1972): Tag for Call is retry
05-05 16:12:07.265: V/TokenRetryPolicy(1972): No attempt remaining, ERROR
05-05 16:12:08.219: I/Choreographer(1972): Skipped 324 frames! The application may be doing too much work on its main thread.
05-05 16:12:08.230: V/RefreshAPICall(1972): Response from server on refresh is: {"status":"success","token":"d5792e18c0e1acb3ad507dbae854eb2cdc5962a2c1b610a6b77e3bc3033c7f64"}
05-05 16:12:08.230: V/VolleyUser(1972): Token from return is: d5792e18c0e1acb3ad507dbae854eb2cdc5962a2c1b610a6b77e3bc3033c7f64
05-05 16:12:08.231: V/TokenRetryPolicy(1972): Cancelled all retry calls
05-05 16:12:08.257: V/SessionManager(1972): New Token In SharedPref is: d5792e18c0e1acb3ad507dbae854eb2cdc5962a2c1b610a6b77e3bc3033c7f64
05-05 16:12:08.257: V/TokenRetryPolicy(1972): Logged new token
आप इस के लिए किसी भी ठीक मिला? या कोई कामकाज? मैं कुछ इसी तरह से अटक गया हूँ। –
@ सुशांतकुनल कृपया नीचे देखें, उम्मीद है कि यह मदद करता है! – Brandon