I used vollay library, sending data to server. I used this tutorial(here)
When i Run app, i get error for below code: ApplicationController.getInstance().addToRequestQueue(req);
error is:
Attempt to invoke virtual method 'void com.example.divid.holo.ApplicationController.addToRequestQueue(com.android.volley.Request)' on a null object reference
plz help me, TNX
ApplicationController class:
public class ApplicationController extends Application {
/**
* Log or request TAG
*/
public static final String TAG = "VolleyPatterns";
/**
* Global request queue for Volley
*/
private RequestQueue mRequestQueue;
/**
* A singleton instance of the application class for easy access in other places
*/
private static ApplicationController sInstance;
#Override
public void onCreate() {
super.onCreate();
// initialize the singleton
sInstance = this;
}
/**
* #return ApplicationController singleton instance
*/
public static synchronized ApplicationController getInstance() {
return sInstance;
}
/**
* #return The Volley Request queue, the queue will be created if it is null
*/
public RequestQueue getRequestQueue() {
// lazy initialize the request queue, the queue instance will be
// created when it is accessed for the first time
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
/**
* Adds the specified request to the global queue, if tag is specified
* then it is used else Default TAG is used.
*
* #param req
* #param tag
*/
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
VolleyLog.d("Adding request to queue: %s", req.getUrl());
getRequestQueue().add(req);
}
/**
* Adds the specified request to the global queue using the Default TAG.
*
* #param req
* #param tag
*/
public <T> void addToRequestQueue(Request<T> req) {
// set the default tag if tag is empty
req.setTag(TAG);
getRequestQueue().add(req);
}
/**
* Cancels all pending requests by the specified TAG, it is important
* to specify a TAG so that the pending/ongoing requests can be cancelled.
*
* #param tag
*/
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Use it, like below in main activity:
final String URL = "xxxxxxxxxxxx";
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "AbCdEfGh123456");
JsonObjectRequest req = new JsonObjectRequest(URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
Define AppController in Manifest Like :
<application
android:name=".AppController"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="#style/AppTheme">
Related
I would like to show my loading animation during all the consecutive calls and then hide it, whatever is the result.
I have a 1 year working expirience in angular 4+, where is simple to concatenate endpoint calls and then do some actions when the calls have ended.
An angular example:
this.showLoadingIndicator()
this.myEndpointService.getA
.pipe(
tap(resultA => this.myEndpointService.getBFromA(resultA)),
switchMap(resultB => this.myEndpointService.getCFromB(resultB)),
tap(resultC => this.myC = resultC),
finally(this.hideLoadingIndicator())
)
.subscribe (
() => this.successDialog('so good so far'),
error => {/*errors*/}
);
and an (limited) example of the EndpointService:
getA(): Observable<any> {
const url = `${this.apiEndpoint}/getA`;
return this.http.get<any>(url);
}
With just few lines of code (I skipped the part about adding headers) I can call multiple endpoint, execute one after another, and finally hide the loadingIndicator no-matter-what.
In android i have a longer code, but with singleton and generics the logic flows nicely.
I have implemented Volley as singleton:
public class VolleyNetworkSingleton {
private static VolleyNetworkSingleton instance;
private static Context ctx;
private RequestQueue requestQueue;
private VolleyNetworkSingleton(Context context) {
ctx = context;
requestQueue = getRequestQueue();
}
/**
* Ensures that the Class is instantiated only once
* and the same instance is used throughout the application.
*
* #return the Class instance.
*/
public static synchronized VolleyNetworkSingleton getInstance(Context context) {
if (instance == null) {
instance = new VolleyNetworkSingleton(context);
}
return instance;
}
/**
* Ensures that the requestQueue is instantiated only once
* and the same instance is used throughout the application.
*
* #return the RequestQueue.
*/
public RequestQueue getRequestQueue() {
if (requestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
requestQueue = Volley.newRequestQueue(ctx.getApplicationContext());
}
return requestQueue;
}
/**
* #param req the request to add
* #param tag the tag to associate the request
* #param <T> the generic Type used
*/
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(tag);
getRequestQueue().add(req);
}
/**
* #param tag used to delete the associated Request
*/
public void cancelAllRequests(String tag) {
getRequestQueue().cancelAll(tag);
}
}
Then i customized the VolleyRequest with some features:
- generic body which is automatically parsed as json,
- generic response which is also parsed back to an Object
- added request headers
public class AuthorizedRequest extends Request {
private static final String TAG = "AuthorizedRequest";
private Response.Listener listener;
/**
* Declare a gson variable which will be used to convert the json response
* to POJO
**/
private Gson gson;
private Object body;
/**
* Declare a Class variable. This Class will represent the POJO. Basically
* this variable will hold the instance of the java object which you
* want as response
**/
private Class responseClass;
private Context context;
/**
* Constructor for your custom class
*
* #param method Http method
* #param url url of the request
* #param requestBody body of the request
* #param responseClass Object type of the response
* #param context the context
* #param listener listener to notify success response
* #param errorListener listener to notify error response
*/
public <T> AuthorizedRequest(int method,
String url,
#Nullable T requestBody,
Class responseClass,
Context context,
Response.Listener listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateDeserializer()).create();
this.listener = listener;
this.body = requestBody;
this.context = context;
this.responseClass = responseClass;
}
/**
* This method needs to be implemented to parse the raw network response
* and return an appropriate response type.This method will be called
* from a worker thread. The response
* will not be delivered if you return null.
*
* #param response Response payload as byte[],headers and status code
**/
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
try {
// First convert the NetworkResponse into a jsonstring.
String jsonString = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers, "utf-8"));
// Then that json string can be converted into the required java.object<Gson>
return Response.success(
gson.fromJson(jsonString, responseClass),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return Response.error(new ParseError(e));
}
}
/**
* This is called on the main thread with the object you returned in
* parseNetworkResponse(). You should be invoking your callback interface
* from here
**/
#Override
protected void deliverResponse(Object response) {
listener.onResponse(response);
}
/**
* Parse the body of the request
*
* #return the parsed body
*/
#Override
public byte[] getBody() {
String parsedBody = new String();
try {
parsedBody = parseBody(body);
return parsedBody == null ? null : parsedBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", parsedBody, "utf-8");
return null;
}
}
/**
* Applies the AccessToken logic and if successful, builds the headers
*
* #return the headers
*/
#Override
public Map<String, String> getHeaders() {
try {
if (MyUtils.isRefreshTokenExpired(context)) {
return null;
}
if (MyUtils.isAccessTokenExpired(context)) {
GoToLogin();
return null;
}
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
return headers;
} catch (IOException e) {
Log.e(TAG, e.getMessage() + e.getStackTrace());
String message = context.getResources().getString(R.string.no_internet_connection);
return null;
}
}
/**
* Converts the object to string
*
* #param obj the object to parse
* #param <T> the object's type
* #return the string of the parsed body
*/
private <T> String parseBody(T obj) {
try {
if (obj == null)
return null;
JSONObject jsonBody = new JSONObject(gson.toJson(obj));
return jsonBody.toString();
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
}
Then i just use it like this:
AuthorizedRequest request = new AuthorizedRequest(
Request.Method.GET,
buildUrl(),
null, /*no body needed*/
MyObject.class, /*what i expect to receive*/
getContext(),
new Response.Listener<MyObject >() {
#Override
public void onResponse(MyObject response) {
if (response.getProp1() == null)
showEmptyPropMessage();
else {
myProp1.setText(response.getProp1());
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
// Add the request to the RequestQueue.
VolleyNetworkSingleton.getInstance(getContext()).addToRequestQueue(request, "GET_MY_OBJECT");
Despite the amount of code needed this works great!
But how do I concatenate multiple request to show the loadingIndicator before calling them and then hiding it just once?
Do i have to put each request inside of another (actually, inside Response.Listener())? Because.. yeah, I can do it (one inside another), and hostestly is not that bad.. but then i will have to hide the loadingIndicator every time there is an error.
Moreover, if wanted to create two chain of calls, that differs just by the order of endpoint call, i will have to write the same code twice.
example getA then getB case:
private void getAandThenB() {
AuthorizedRequest reqA = new AuthorizedRequest(Method, url, null, A.class, context, Response.Listener { getB();}, Response.ErrorListener{});
VolleyNetworkSingleton.getInstance(getContext()).addToRequestQueue(request, "GET_A");
}
private void getB() {
AuthorizedRequest reqB = new AuthorizedRequest(Method, url, null, B.class, context, Response.Listener { /*do something*/}, Response.ErrorListener{});
VolleyNetworkSingleton.getInstance(getContext()).addToRequestQueue(request, "GET_B");
}
If in the same class i also want to refresh just A, i have to write another function, lets call it getJustA() where the only difference is the action in the response:
private void getJustA() {
AuthorizedRequest reqA = new AuthorizedRequest(Method, url, null, A.class, context, Response.Listener { refreshA()}, Response.ErrorListener{});
VolleyNetworkSingleton.getInstance(getContext()).addToRequestQueue(request, "GET_A");
}
As you can see, just to express a simple case scenario, this get out of hands very quickly.
I am writing a reactive wrapper over volley library to send http request easily in my app. Here is the class:
/**
* Used to send a http GET/POST request.
*/
public class BasicRequest {
public static final String LOG_TAG = "BasicRequest";
public static final int GET_REQUEST = Request.Method.GET;
public static final int POST_REQUEST = Request.Method.POST;
private final int mRequestType;
private final String mServiceLocation;
private final Map<String, String> mParams;
/**
* Keeps track of all the request for this object. Will be helpful when we need to cancel
* the request when someone disposes the subscription.
*/
private List<StringRequest> mStringRequests = new ArrayList<>();
private Context mContext;
private int mRequestTimeout = BASIC_REQUEST_DEFAULT_TIMEOUT;
public BasicRequest(Context context,
String serviceLocation,
int requestType,
final Map<String, String> params) {
mContext = context;
mRequestType = requestType;
mServiceLocation = serviceLocation;
mParams = params;
}
private void fireRequest(final SingleEmitter<String> e) {
StringRequest stringRequest;
if(mRequestType == GET_REQUEST) {
stringRequest = new StringRequest(Request.Method.GET, mServiceLocation,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
e.onSuccess(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
e.onError(error);
}
});
} else {
stringRequest = new StringRequest(Request.Method.POST, mServiceLocation,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
e.onSuccess(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
e.onError(error);
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return mParams;
}
};
}
mStringRequests.add(stringRequest);
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
mRequestTimeout,
ConnectionUtils.BASIC_REQUEST_DEFAULT_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleyInstance.getInstance(mContext).addToRequestQueue(stringRequest);
}
/**
* Returns a Single observable for results. Queues the request on Subscription. Must be
* called only once during the lifetime of object. Calling multiple times will return null.
* Expect to get VolleyException in case of error.
* #return Single observable for String results. If it's is used for second time, it will
* return null.
*/
#Nullable
public Single<String> get() {
return Single.create(new SingleOnSubscribe<String>() {
#Override
public void subscribe(#NonNull SingleEmitter<String> e) throws Exception {
fireRequest(e);
}
}).doOnDispose(new Action() {
#Override
public void run() throws Exception {
for (StringRequest stringRequest: mStringRequests) {
stringRequest.cancel();
}
}
});
}
/**
* Set the request timeout for this request.
* #param requestTimeout time in milliseconds.
*/
public void setRequestTimeout(int requestTimeout) {
mRequestTimeout = requestTimeout;
}
Now the problem is when somebody disposes a subscription all the request corresponding to all the subscription will be stopped. Is there a way I can only stop the request for which subscription is disposed?
I know once way achieving it would to enforce that only one subscription can be maintained and if someone calls get again, cache'd observer will be returned. Is there a better way of disposing http request based on subscription disposal?
You don't need to manage it outside fireRequest, SingleEmitter has setCancellable method exactly for that, do the cancellation there, and RxJava will make sure to call it when someone dispose the Observable.
add at fireRequest() method, and remove the doOnDispose :
e.setCancellable(()-> stringRequest.cancel());
*how to create interface use any where android Json Volley Library please help me *
public void getJsonRequest(){//Create interface and jsonObjectRequest
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET,url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
list =parseJSONRequest(response);// create interface
adapter.setAllLinks(list); // create interface
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
errorJson.setVisibility(View.VISIBLE);
String map = VolleyErrorException.getErrror(error, getContext());
errorJson.setText(map);
}
});
requestQueue.add(jsonObjectRequest);
}
Here is solution. I have created a static method in a separate class nammed APIManager.
/**
* The method to create a Request with specific method except GET
*
* #param method The request Method ex. (Request.Method.POST)
* #param params The parameters map
* #param url The base url of webservice to be called
* #param requestTag The request Tag to assign when putting request to request queue
* #param listener The listener for request completion.
*/
public static void createPostRequest(int method, final Map<String, String> params, String url, String requestTag, final OnRequestCompletedListener listener) {
JsonObjectRequest request = new JsonObjectRequest(method, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
listener.onRequestCompleted(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
listener.onRequestError(getErrorMessageFromVolleyError(error));
}
}) {
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded";
}
#Override
public byte[] getBody() {
Uri.Builder builder = Uri.parse("http://example.com")
.buildUpon();
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.appendQueryParameter(entry.getKey(),
entry.getValue());
}
return builder.build().getEncodedQuery().getBytes();
}
};
AppController.getInstance().addToRequestQueue(request, requestTag);
}
/**
* The interface for callback when API Request completes.
*/
public interface OnRequestCompletedListener {
/**
* The interface method called when API call successfully completes.
*
* #param jsonObject The JSONObject recieved from the API call.
*/
void onRequestCompleted(JSONObject jsonObject);
/**
* The interface method called when API call recieves any Error.
*
* #param errorMessage The error message
*/
void onRequestError(String errorMessage);
}
/**
* The method to convert volley error into user readable string message.
*
* #param error The volleyError recieved during API call
* #return The String containing the message related to error
*/
public static String getErrorMessageFromVolleyError(VolleyError error) {
if (error instanceof TimeoutError) {
return AppController.getContext().getString(R.string.time_out_error_message);
}
if (error instanceof NoConnectionError) {
return AppController.getContext().getString(R.string.no_connection_error_message);
}
if (error instanceof ServerError) {
return AppController.getContext().getString(R.string.server_error_message);
}
if (error instanceof NetworkError) {
return AppController.getContext().getString(R.string.network_error_message);
}
if (error instanceof ParseError) {
return AppController.getContext().getString(R.string.parse_error_message);
}
return null;
}
To call this method use it in any activity or fragment class like this way.
private void getEvaultFiles() {
Map<String, String> params = new HashMap<>();
params.put("EvaultId", item.id);
APIManager.createPostRequest(Request.Method.POST,params, AppConstants.GET_EVAULT_FILES_URL, "GETEVAULTFILES", new APIManager.OnRequestCompletedListener() {
#Override
public void onRequestCompleted(JSONObject jsonObject) {
Utils.hideProgressAndShowContent(EvaultDetailActivity.this);
listFiles.clear();
tvEmpty.setText("No Files to display");
try {
JSONArray files = jsonObject.getJSONObject("Result").getJSONArray("Files");
for (int i = 0; i < files.length(); i++) {
EvaultFile file = new EvaultFile();
JSONObject temp = files.getJSONObject(i);
file.name = temp.getString("FileName");
file.size = temp.getString("FileSize");
file.fileurl = temp.getString("FilePathFullImage");
listFiles.add(file);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onRequestError(String errorMessage, JSONObject data) {
}
});
}
I want to create one base class for volley library and want to access the response and Error on the Activity where i called the volley request.because of this my code will optimize.
Personally am using following classes for handling volley.you can revert it as per the requirement.
Volley Request Queue Helper :
public class VolleyHelper {
private static final String TAG = VolleyHelper.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static VolleyHelper mInstance;
public VolleyHelper (Context context) {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(context);
}
}
public static synchronized VolleyHelper getInstance(Context context) {
if (mInstance == null) {
mInstance = new VolleyHelper(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Ideally you should have one centralized place for your Queue, and the best place to initialize queue is in your Application class. Above snippet interpret how this can be done
Volley Error Helper
public class VolleyErrorHelper {
/**
* Returns appropriate message which is to be displayed to the user
* against the specified error object.
*
* #param error
* #param context
* #return
*/
public static String getMessage(Object error, Context context) {
if (error instanceof TimeoutError) {
return context.getResources().getString(R.string.generic_server_down);
} else if (isServerProblem(error)) {
return handleServerError(error, context);
} else if (isNetworkProblem(error)) {
return context.getResources().getString(R.string.no_internet);
}
return context.getResources().getString(R.string.generic_error);
}
/**
* Determines whether the error is related to network
*
* #param error
* #return
*/
private static boolean isNetworkProblem(Object error) {
return (error instanceof NetworkError) || (error instanceof NoConnectionError);
}
/**
* Determines whether the error is related to server
*
* #param error
* #return
*/
private static boolean isServerProblem(Object error) {
return (error instanceof ServerError) || (error instanceof AuthFailureError);
}
/**
* Handles the server error, tries to determine whether to show a stock message or to
* show a message retrieved from the server.
*
* #param err
* #param context
* #return
*/
private static String handleServerError(Object err, Context context) {
VolleyError error = (VolleyError) err;
NetworkResponse response = error.networkResponse;
if (response != null) {
switch (response.statusCode) {
case 409:
return context.getResources().getString(R.string.user_exists);
case 404:
break;
case 422:
break;
case 401:
try {
// server might return error like this { "error": "Some error occured" }
// Use "Gson" to parse the result
HashMap<String, String> result = new Gson().fromJson(new String(response.data),
new TypeToken<Map<String, String>>() {
}.getType());
if (result != null && result.containsKey("error")) {
return result.get("error");
}
} catch (Exception e) {
e.printStackTrace();
}
// invalid request
return error.getMessage() != null ? error.getMessage() : context.getResources().getString(R.string.generic_error);
default:
return context.getResources().getString(R.string.generic_server_down);
}
}
return context.getResources().getString(R.string.generic_error);
}
}
Volley Response Helper
public class VolleyResponseHelper {
/**
* Returns appropriate message which is to be displayed to the user
* against the specified response .
*
* #param code
* #param context
* #return
*/
/* 0 - Request from registration */
/* 1 - Request from login */
/* 2 - Request from New post */
public static String getMessage(String code, int from, Context context) {
int mCode = Integer.parseInt(code);
String message = null;
switch (mCode) {
case 409:
if (from == 1 || from == 0) {
message = context.getResources().getString(R.string.user_exists);
}
return message;
case 200:
if (from == 1 || from == 0) {
message = context.getResources().getString(R.string.success);
} else if (from == 2) {
message = context.getResources().getString(R.string.np_done);
}
return message;
case 401:
if (from == 1) {
message = context.getResources().getString(R.string.user_not_exists);
}
return message;
default:
return context.getResources().getString(R.string.generic_error);
}
}
}
Inside volley onErrorResponse
#Override
public void onErrorResponse(VolleyError error) {
String errorString = VolleyErrorHelper.getMessage(error, context);
if (errorString != null) {
showAlert(errorString);
}
}
For more clear about usage i have posted my code revert it like your requirement
private void getDetails(Map<String, String> params) {
SalonJsonObjReq arrayReq = new SalonJsonObjReq(Request.Method.POST, Constants.SALON_DETAILS, new JSONObject(params), new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
populate(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideProgressDialog();
String errorString = VolleyErrorHelper.getMessage(error, DetailsScreen.this);
if (errorString != null) {
Util.showAlert(DetailsScreen.this, getResources().getString(R.string.error), errorString);
}
}
}, null);
showProgressDialog(getResources().getString(R.string.loading));
VolleyHelper.getInstance(getApplicationContext()).addToRequestQueue(arrayReq);
}
ResponseHelper also you can use on this way.apply your logic :)
Check this for more.
I use VolleyService in Util app folder as following :
public class VolleyService {
private static VolleyService instance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
private VolleyService(Context context) {
requestQueue = Volley.newRequestQueue(context);
imageLoader = new ImageLoader(requestQueue, new ImageLoader.ImageCache() {
private final LruCache<String, Bitmap> cache = new LruCache<String, Bitmap>(20);
#Override
public Bitmap getBitmap(String url) {
return cache.get(url);
}
#Override
public void putBitmap(String url, Bitmap bitmap) {
cache.put(url,bitmap);
}
});
}
public static VolleyService getInstance(Context context) {
if (instance == null) {
instance = new VolleyService(context);
}
return instance;
}
public RequestQueue getRequestQueue() {
return requestQueue;
}
public ImageLoader getImageLoader() {
return imageLoader;
}
}
And when I need an instance i just use :
VolleyService.getInstance(context)
Or creating the request :
RequestQueue queue = VolleyService.getInstance(this.getContext()).getRequestQueue();
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// we got the response, now our job is to handle it
try {
updateArticleData(response, syncResult,categoryID);
} catch (RemoteException | OperationApplicationException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//something happened, treat the error.
Log.e("Error", error.toString());
}
});
queue.add(request);
I'm have add volley for request to get Json object and cache data. but when i clear all cache, seem all data not delele.
Because when i turn off my network and restart my app .It still using cache.
I do the following code
public class AppController extends Application {
public static final String TAG = AppController.class.getName();
public static AppController mIntance;
private RequestQueue requestQueue;
private ImageLoader imageLoader;
/**
* onCreate of class that is extend Application always call first when app laucher . to benefit
* create object singleton.
*
* #param err
* #param context
* #return
*/
#Override
public void onCreate() {
super.onCreate();
mIntance = this;
}
public static synchronized AppController getIntance() {
return mIntance;
}
public RequestQueue getRequestQueue() {
/*
* if (requestQueue == null) { requestQueue =
* MyRequest.newRequestQueue(getApplicationContext()); }
*/
if (requestQueue == null) {
requestQueue = Volley.newRequestQueue(getApplicationContext());
}
return requestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// hoa ra settag la cho req nay ,. minh cu tuong no set cho c�i
// requestqueue
req.setTag(tag.equals("") ? TAG : tag);
getRequestQueue().add(req);
}
// using request with string default
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelRequest(Object tag) {
if (requestQueue != null) {
requestQueue.cancelAll(tag);
}
}
public void cancelAllRequest() {
if (requestQueue != null) {
requestQueue.cancelAll("feed_request");
}
}
/*
* clear some cache
*/
public void DeletelCacheFromSomeURL(ArrayList<String> array) {
for (int i = 0; i < array.size(); i++) {
requestQueue.getCache().remove(array.get(i));
}
}
}
i have clear all cache flowing
AppController.getIntance().getRequestQueue().getCache()
.clear();
Anyone explain and give me solution . thank !