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);
}
});
Related
I need to make multiple calls to API REST with Retrofit and show the response in a ListView, but I don't know how to do this and this code doesn't work.
Model
#GET("apks/{sha256}")
Call<DatoAPI> getTask2(#Path("sha256") String hash, #Query("Authorization") String key);
Implementation
for (String s: hash) {
Call<DatoAPI> call = services.getTask2(s, API.API_KEY);
call.enqueue(new Callback<DatoAPI>() {
#Override
public void onResponse(Call<DatoAPI> call, Response<DatoAPI> response) {
if (response.isSuccessful()) {
datoAPI = response.body();
items.add(datoAPI.getApp());
}
}
#Override
public void onFailure(Call<DatoAPI> call, Throwable t) {
Toast.makeText(getApplicationContext(),t.getMessage(),Toast.LENGTH_LONG).show();
}
});
}
Also I tried with call.execute() and same problem
I want to show this response in a ListView but it doesn't work.
First of all you need to understand the differences between Retrofit's Call#enqueue() and Call#execute() methods.
enqueue() method is Asynchronous which means you can move on to another task before it finishes
execute() method is Synchronous which means, you wait for it to finish before moving on to another task.
And in your case, you're using for loop to execute multiple requests in a single stretch.
Now, if you use for loops to execute network operation, the network operation will not stop for loops from going to the next iteration. Do not expect that the API will always respond in a fast enough way before going to for loops next iteration. That's a bad idea.
If you use Retrofit's execute() method, it will not allow you to continue to next line (or iteration) as its Synchronous behavior, plus it throws NetworkOnMainThreadException and IOException. Hence, you need to wrap the request in an AsyncTask and handle IOException.
I'd recommend you to use RxAndroid with RxJava instead of using for loops. There are plenty of tutorials out there on this topic.
Refer to the following StackOverflow questions to solve your problem.
How to make multiple request and wait until data is come from all the requests in Retrofit 2.0 - Android?
Asynchronous vs synchronous execution, what does it really mean?
Adjust the code as per your requirements.
Good luck!
I am very new to RxJava and can't seem to find figure out the solution to this use case. I have been researching on this for 2 days now and no luck.
I have 2 Singles, remote and cache, to register a user in my app
I first call remote which saves the user data on a server, and returns a custom code to indicate successfully saved. I only want to call cache after I have checked the custom code from remote and gotten a success. If custom code comes as failure, I want to return that, and not go to the cache at all
The operator, which you're looking for, is flatMap. Example:
remoteApi.login().flatMap(new Function<String, SingleSource<String>>() {
#Override public SingleSource<String> apply(String response) throws Exception {
if (response.equals("success")) {
// do what you want to do with cache
return cache.save(response);
}
return Single.just(response);
}
}).subscribe(yourObserver);
Don't forget to use subscribeOn and observeOn...
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.
I'm using ACRA to report exceptions and would like to include the last API call (and potentially the response body) as part of the custom data that can be supplied. I've been looking over the available RestAdapter.Builder interfaces but don't see one that supplies what I'm looking for. Effectively, I'd like access to what's put into Logcat when full logging is enabled.
Is there a way to get the last URL, headers, and response body within Retrofit so I can set custom ACRA fields?
Retrofit allows specifying a Profiler which gets invoked immediately before and after requests are made.
public interface Profiler<T> {
T beforeCall();
void afterCall(RequestInformation info, long elapsedTime, int statusCode, T beforeData);
}
While you don't get access to the actual body, you get a good bit of information about it.
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);
}