I'm putting the volley requests to an array and then i' using for statement for adding request to volley queue like this (pseudo code) :
ArrayList<Requst> array = new ArrayList<Requst>()
volleyRequest req = //some code
volleyRequest req2 = //some code
array.add(req)
array.add(req2)
And on another class i'm using :
for(Requst r : array )
{
volley.newRequestQueue.add(req, tag);
}
But this loop did not continue until first request does not finished!
What should i do?
Is there any way for adding array of requests to volley without loop?
Use the singleton pattern to add multiple request in volley library as specified in the link
Check that out, you need to create a RequestQueue:
https://developer.android.com/training/volley/requestqueue.html
Related
I am facing a problem when trying to send an Http post request to the backend of my application. I am trying to send a post request like this :
{"a":[{"data":"https://news.google.com/rss/search?q=Pallini&hl=el"}]}
and instead it is being send something like this:
{"a":[{"data\":\"https://news.google.com/rss/search?q=Pallini&hl=el"}]}
or:
{"a":[{\"data\":\"https://news.google.com/rss/search?q=Pallini&hl=el\"}]}
So, I have a list that contains strings and every time I add the string that I want it to be shown in the json array, the code is like this:
var arrayListForA: ArrayList<JsonElement>? = arrayListOf()
config.forEach {
arrayListForA?.add(it)
}
The config is an another list that contains the jsons object as strings.
My question is, if there is any way to create the http post request body in Kotlin with the use of classes, objects etc, in a more automated way ?! for example, instead of a list with strings, I could use a list with Data class objects.
val dataList : ArrayList<Data> = arrayListOf()
where Data class is :
#Parcelize
data class Data(
#Expose #SerializedName("data") val data: String?
) : Parcelable
Is there any solution/idea to send the body of the post request as I need it ?
You can use retrofit and okhttp for this in Android. Retrofit helps you deal with networking easily. Also you will be able to post a custom data model as body in the api request. The interface will look something like given below. You can read more about retrofit here. retrofit
#POST(Urls.PURCHASE)
fun purchase(#Body purchaseAddonReqModel: PurchaseReqModel):Single<BaseResponse<EmptyResponse>>
Here you can add your custom model by adding the #Body annotation
I call a Rest API of salesforce by post method:
url = "https://test-dev-ed.my.salesforce.com/services/apexrest/AccountUsers/"
client = OkHttpClient()
val jsonIn = FormBody.Builder()
.add("email",URLEncoder.encode("dt1#gmail.com", "UTF-8"))
.add("password", URLEncoder.encode("1","UTF-8"))
.build()
request = Request.Builder()
.post(jsonIn)
.header("Authorization", "Bearer "+accesstoken)
.addHeader("Content-Type","application/x-www-form-urlencoded")
.url(url)
.build()
response = client.newCall(request).execute()
This is rest api:
#HttpPost
global static ID createUser(String email, String password) {
AccountUser__c us=new AccountUser__c();
us.Email__c=email;
us.Password__c=password;
us.Status__c=0;
insert us;
return us.Id;
}
But result return is error:
[{"errorCode":"UNSUPPORTED_MEDIA_TYPE","message":"Content-Type header specified in HTTP request is not supported: application/x-www-form-urlencoded"}]
I had try change application/json to application/x-www-form-urlencoded , but still can't resolve.
I try call a Get method, it is ok.
Why Post method occur error [Content-Type header specified in HTTP request is not supported]?
I would like to suggest a better resolution. Retrofit Library
Even though it is not mandatory to use Retrofit, these are few eye catchy aspects which makes it reliable and handy in similar use case of yours.
Why to use Retrofit?
Type-safe REST Adapter that makes common networking tasks easy
For POST operations, retrofit helps in assembling what needed to be submitted. Eg:- Generating URL encoded form.
Takes care of URL manipulation, requesting, loading, caching, threading, synchronization, sync/async calls
Helps to generate URL using type-aware generated code tied to specific REST API
Parsing JSON using GSON
Retrofit is an API adapter wrapped over OkHttp
The problem that you are facing can be resolved using retrofit like this.
public interface APIConfiguration{
#Headers({"Accept:application/json",
"Content-Type:application/x-www-form-urlencoded"})
#FormUrlEncoded
#POST("user/registration")
Observable<DataPojo> registrationAPI(#FieldMap(encoded = true) Map<String, String> params);
}
That's it, with few annotation the library takes care of Form URL
Encoding and related dependencies.
As it is inappropriate to start from corresponding Retrofit dependencies and sample code, you can go through Reference One and Reference Two for more details.
As per my understanding just checkout the difference the content type header "application/x-www-form-urlencoded" is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type "multipart/form-data" should be used for submitting forms that contain files, non-ASCII data, and binary data.
The content "multipart/form-data" follows the rules of all multipart MIME data streams.
https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
Also try your http request by setting your content type header as multipart/formdata.
I am trying to make a simple weather app using retrofit library. I want the city name to be dynamic. This is what i have done so far:
full url:
http://api.openweathermap.org/data/2.5/forecast/daily?q=dhaka&cnt=7&appid=1111
base url:
http://api.openweathermap.org/
in the main activity
LinkedHashMap<String,String>data=new LinkedHashMap<>();
data.put("q",targetCity);
data.put("cnt",Integer.toString(7));
data.put("appid",getString(R.string.api_key));
Call<WeatherResponse>weatherResponseCall=weatherServiceApi.getAllWeatherReport(data);
and in my api interface:
#GET("data/2.5/forecast/daily?")
Call<WeatherResponse>getAllWeatherReport(#QueryMap LinkedHashMap<String,String>data);
I am neither getting any error, nor any response data.
Please help.
You aren't executing the call function...
WeatherResponse response = call.execute().body();
If I were you, I would try using a ResponseBody from okhttp to get the data returned. Then using response.string() you can see what's retrieved from the request.
Or, to log the body data of each request/response you should add this interceptor when building your Retrofit object:
OkHttpClient client = httpClient.addInterceptor(interceptor.setLevel(HttpLoggingInterceptor.Level.BODY))
.build();
Retrofit retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
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.
anyone know how can I send a JSON param to Volley ? Seeing the library, I watch the methods getParams that return a Map , but I need to send a Json with the form
{"medias" : [1,2,3,4,5] }
but if I send it with the getParams method, my server receive some like this : "medias" : "[1,2,3,4,5]" (the second part as a string)
any help?
A JsonObjectRequest in Volley allows you to pass your JSONObject into the constructor. Just create a JSONObject, add your JSONArray and use it to create your JsonObjectRequest.
Here's an example of how to create a JSONArray:
https://stackoverflow.com/a/13468303/736496