I'm confused about post and get request in android volley.
Can you explain me their differences?
And can I use post method with no Param to get a JSON from URL?
Their difference is in functions defined in server.
In simple words, With a GET method, you are sending your data via the URL. While, with A POST method, data is embedded in the form object and sent directly from your browser to the server. ... We usually use GET to identify and dynamically render pages and POST to send form data but it's not always the case.
and answer of your second question is yes you can but that's not a good idea get would be better for that. here is a example of how you can send requests using Volley Library
StringRequest request = new StringRequest(Request.Method.POST, "www.example.com", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> parameters = new HashMap<>();
return parameters;
}
#Override
public String getBodyContentType() {
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
AppController.getInstance().addToRequestQueue(request, tag);
Are you working on server or server is handled by someone else?
In general, person who works on server decides the method.
Like if you work on JAVA server, then say an API end point is https://sample.api.someurl.com/userInfo/
TO maintain some consistency server programmer may use GET method to get userInfo and he may use POST method to update user info and he may use DELETE method to delete the existing user info.
In this example, your API end point remains same but the request method decides how that end point will behave.
In other example, to save time, a server developer may redirect all the requests to one method and handle it there, so no matter you call GET, POST or DELETE API will return same response.
So yes, Its not Android or UI developer who decides the Method alone, Major role of deciding which method to use is decided by server programmer.
P.S. If you are working on server too, then good practice is to use GET to get the info, POST method to update or add the info and DELETE to remove the info.
Related
I have a for loop , which is creating different url and then i am pushing the urls in the Volley RequestQueue using add function.
I have a question that , will the response listner will be responding in the order of the request added to the RequestQueue or it will be random based on the server responses of the requests made?
I am using VolleySingleton approach.
Volley RequestQueue class manage asynchonous requests queue.
It means Volley send requests on a FIFO (first in first out) model, but since responses can be quite long to come back, it handle responses in no particular order.
You can't use it if you want the result of a first request to be used in a second request.
However, you can visibly use RequestFuture class to use Volley on a synchonous model:
Can I do a synchronous request with volley?
By default, Volley RequestQueue will use 4 concurrent Threads to process the Requests added to the Queue. This may be changed by extending the RequestQueue class and passing the desired Thread pool size as the third parameter to super contructor.
Passing 1 to the constructor will result in the RequestQueue processing one Request at a time :-)
Reference
No! Android volley process each requests in request queue Asynchronously:
Refer the architecture image:
Each requests in the request queue will be processed by the network threads and also you can limit the network dispatcher thread count check here
Assuming that the default behavior is to send multiple requests on separate concurrent threads, then the order of the responses then becomes dependent on the total response time for each individual request.
As to identifying the responses (other than the data itself), it seems like you should be able to instantiate a Response.Listener implementation with a unique request identifier (original URL or int) such that when the response handler is invoked it is able to differentiate the original request.
public class JSONProcessor implements Response.Listener<JSONObject> {
private String url;
private int reqCode;
public JSONProcessor (String reqUrl) {
this.url = reqUrl
}
public JSONProcessor (int reqCode) {
this.reqCode = reqCode;
}
public void onResponse(JSONObject response) {
// use this.url or this.reqCode to determine original request
// process response
}
}
Alternatively, use different implementations of Response.Listener for each endpoint you expect to be processing.
In general, in my opinion it is best to be completely data driven if at all possible.
I use ion library for downloading files in my app. I want to read the response headers, check a particular header and either cancel or continue the download. Of course I can execute the HEAD query, check the header, and then execute the GET query. But I want to execute only one request.
Is there a way to get a callback when received all the headers, handle them and either continue or cancel the download?
Use the onHeaders callback.
.onHeaders(...)
https://github.com/koush/ion/blob/master/ion/src/com/koushikdutta/ion/builder/RequestBuilder.java#L186
I found another solution. Maybe it's better?
Ion.getDefault(<Context>).getHttpClient().insertMiddleware(new SimpleMiddleware()
{
#Override
public void onHeadersReceived(OnHeadersReceivedDataOnRequestSentData data)
{
super.onHeadersReceived(data);
}
});
I am creating app that consumes REST Api. My API has ability to login/logout in order to access private data. I am creating consumer(client Android app) with Retrofit + Robospice + Jackson.
Everything was okey, but than authorization part came into play.
I need to provide token and other credentials in my request Authorization Header.
This can be easily done by using RequestInterceptor. Here is complete tutorial how to use basic Authentication.
Basic Authentication with Retrofit .
It is clear how to implement this. But in my case I also have resources that can be accessed without credentials.
Here is part of my API declared with Retrofit Annotations
public interface MalibuRestApi {
//Doesn't need credentials
#GET("/store/categories")
Category.List categoryList();
//Doesn't need credentials
#GET("/store/categories/{id}/products")
Product.List productList(#Path("id")int categoryId);
// Needs credentials
#POST("/store/users/{id}/logout")
// Needs credentials
User logout(#Path("id") int id,#Body Credentials userCredentials);
// Needs credentials !!!!!!!!!!!!!!!!!!!!
#POST("/store/users/{id}/orders/")
void makeAnOrder(#Path("id") int userId,#Body Order order,Callback<Void> callback);
}
Please have a look on makeAnOrder method. It uses POST body to pass details about order. So combining credentials and order seems horrible and not efficient, and I won't use it under no circumstances.
It is possible to use interceptor.
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
if
String token = .... // getting token.
request.addHeader("Accept", "application/json");
request.addHeader("Authorization",token);
}
});
I can filter requests and add Auth headers where I need them according to request URL, but ......
According to the discussion here.
#JakeWharton
The relative URL is not exposed in the request interceptor because it
may not be fully resolved yet. A request interceptor has the ability
to perform path replacements and append query parameter
There is one possible workaround.
#powerje
I'm not sure how to access the relative URL in RequestInterceptor but
the solution I used in a similar situation was to check my UserManager
(a global which manages the currently logged in user) to see if a user
is logged in, if they are I add the auth header, otherwise I don't.
I have already similar class Session manager that is created in custom Application class, so I assume that it will live until application(linux dalvik/art process) is destroyed.
So it is possible to do something like this.
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
sessionManager =(SessionProvider) getApplicationContext().getSessionManager();
if(sessionManager.userLoggedIn) {
String token = .... // getting token.
request.addHeader("Accept", "application/json");
request.addHeader("Authorization",token);
}
}
I haven't tested this yet, but it pretends to work.
In this case redundant headers are passed to public resource requests, that don't really require them.
So maybe this can be a sort of solution not a question, but I really need some advice about any other ways (maybe not better) to solve this problem.
I will be grateful for any help.
It is easy to maintain progress bar state when i use AysncTask with fragments Callback but how should i achieve it with volley? I can;t use AsyncTask because it is outdated and volley is better and faster.
Any Help or Hint will be grateful.
I am using google's volley to Post and Get Requests
I think there are misconceptions here.
First off, Volley faster than AsyncTask.
This is comparing apples and oranges. They both use threads. Volley threads are not any faster than the threads in async task. The queues are separate but that is about it. In API 11 & higher you are allowed to use your own threadpool for AsyncTask instances.
Second, define better.
Volley is designed for sending a lot of light payloads (GET/POST) to a server and getting back pretty quick responses. These responses can then be used by the caller.
AsyncTask is designed to complete a given task off the UI thread and provide various callbacks as to the state of that task.
For your ProgressBar I am assuming you are trying to determine the progress of a request that is being executed. In the Volley world, since these are expected to be tiny, you have pretty much 3 states.
Not Started
Executing(also contains start parsing)
Done (comprised of success, error and cancelled and such)
As you know with AsyncTask there is a callback for onProgress when using publishProgress. So your instance can define anything it wants to send through as an indication of progress.
If your payload is big and will take time to transfer to the server, Volley may not be appropriate. Volley doesn't do a great job or even try to do a great job of sending large payloads to and from a server. The reason is that this just isn't what it is meant for. Like it requires that all payloads, upload and receive can fit in memory entirely. So If you have a few volley requests going all over, and each one with like a 1MB payload and a 1MB response, you could see this adding up pretty quickly. You would need a streaming option to better handle that.
Volley is great library but consider what it is recommended to be used for. Read the documentation and implementation of the code for more info.
If you are doing something that is going to take a rather long time, I would write a specific request type in volley that sends and streams content to and from. That way you can tell how much work is left with the request. I am assuming you are using bytes sent and receive as the measure for progress.
you can add a listener to the queue which is executed when the request end
mRequestQueue.add(yourRequest);
mRequestQueue.addRequestFinishedListener(new RequestQueue.RequestFinishedListener<String>() {
#Override
public void onRequestFinished(Request<String> request) {
if (progressDialog != null && progressDialog.isShowing())
progressDialog.dismiss();
}
});
It's a pretty simple fix. Before you make your volley request, call the method progress.show(), and then on your response, call progress.dismiss() Just did this and it works great!
It's very easy to do that.. see the below code snippet
sendJsonRequest(){
///ENABLE PROGRESS BAR HERE
enableProgressBar();
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.GET, URL, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
hideProgressDialog();
System.out.println(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
hideProgressDialog();
}
});
queue.add(jsObjRequest);
}
I am making an API call to a web service from the android application the problem is that it returns around 22000 records, I am loading this into an array after i convert each record into an object then assign that Array to a ListView. What is the fastest/best way to fetch this data from the web service? (buffer) ? and what are the best practices for this type of issues.
I would recommend using a library to handle your data call...
Please try using Android Query; specifically, see the section entitled Asynchronous Network.
This AQuery library (AndroidQuery) is lightweight, and requires only 1 jar SMALL jar file. It can be used with Maven or Gradle Android projects as well. It allows you to EASILY fetch XML or JSON data from a remote server in either asynchronous or synchronous fashion. I have used it many times with a JSON back-end, and it is a real timesaver.
This library also allows you to specify a ProgressBar that will automatically appear and disappear during the network download process.
Here is an example of an HTTP call to a JSON back-end, asynchronously:
public void asyncJson(){
//perform a Google search in just a few lines of code
String url = "http://www.google.com/uds/GnewsSearch?q=Obama&v=1.0";
aq.ajax(url, JSONObject.class, this, "jsonCallback");
}
public void jsonCallback(String url, JSONObject json, AjaxStatus status) {
if(json != null) {
//successful ajax call
} else {
//ajax error
}
}
AQuery can also simplify other aspects of Android programming (such as eliminating the findViewById() calls for many scenarios).