I need to make a JSON Request and set UI depending on its response, so it would nice to make it in onCreate in the same thread.
Speaking about RequestFuture, I can't reliably use it for this, or I don't know how to do it.
RequestFuture<JSONObject> future = RequestFuture.newFuture();
JsonObjectRequest request = new JsonObjectRequest(URL, null, future, future);
requestQueue.add(request);
try {
JSONObject response = future.get();
count = response.getIn("int");
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}catch (JSONException e) {
Toast.makeText(getActivity(), e.toString(), Toast.LENGTH_LONG).show();
}
I tried this, but its dont work.
If someone know pls show an example how to get data from JSONObject and dont do nothing befor data is goten and than use that values to set some Views.
as there is getActivity() in your code, i bet you are in a fragment.
to do something on UI thread you could call something like this
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
// your UI-related code goes here
}
});
Using Volley you have listeners of response when succeed and an error listener when server has a respone with error code (500, 401).
So you can create a JSONObjectRequest like the following code lines:
JSONObjectRequest jsObjRequest = new JsonArrayRequest
(REQUEST_URL, new Response.Listener<JSONObjectRequest>() {
#Override
public void onResponse(JSONObjectRequest response) {
// this code will be executed when response comes and you can set your views, the way is depending where you are (fragment, activity, etc), you can do runOnUiThread
Log.d("Hello", "You can do whatever you want wen data is goten");
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error","You can show an error dialog here ");
}
});
You have to add the above object created to the HTTQueue and it will be executed at its time. Hope it helped !
if you are using volley then you can use the listeners. You can also refer this https://developer.android.com/training/volley/simple.html . In onResponse or onError you can do the UI changes that you want.
JsonArrayRequest request = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
});
Related
A crash is reported in Volley JsonObjectRequest and exactly in its onErrorResponse block. I cannot change the webservice output to test onErrorResponse block and it's important to debug this code block.
Can anyone tell me how to force the code to go to this part?
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "MY_URL", null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// Which code should I add here to force the code to go to onErrorResponse
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
...
// I want to debug this code block
}
});
I tried response = null; in onResponse but it caused a crash and it didn't go to onErrorResponse.
As #Vivek Mishra said in comments, I tried to set an invalid URL like "https://stackoverflow.com/" instead of "MY_URL" (which was a valid API URL), and it went to onErrorResponse.
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, "https://google.com/", null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// OnResponse Codes
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// OnError Codes
}
});
So I've run into a problem in my code, where I need to get a JSONString from my server with volley. And then I have to parse the String into a JSONObject and then continue doing stuff with that.
My problem here is, that Volley gives the response too late, meaning my string that I want to parse is always empty because its not initialised yet.
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchURLBuilder, future, future);
// new Response.Listener<String>() {
// #Override
// public void onResponse(String response) {
// writeToSharedResponse(response_for_search, response);
// }
// },
// new Response.ErrorListener() {
// #Override
// public void onErrorResponse(VolleyError error) {
// Log.d("Error!!:" + error.getMessage(), "");
// }
// });
requestQueue.add(stringRequest);
String response = "";
try {
response = future.get(60, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
String responseString = m.getString(response_for_search, new String());
pieceDTOList = getPiecesDTOFromJSON(responseString);
Here is a snippet of my code. As you can see I already tried to make a "future" call to block and wait for the answer, but it just times out every time. The commented out bit, is the part I actually wanted to use from the beginning, but that returns the response to late. Since its asynchronous and accesses the server w/e it wants.
writeToSharedResponse just writes the answer into a sharedPreferences variable.
private SharedPreferences m;
private SharedPreferences.Editor editor;
private RequestQueue requestQueue;
public DbParser(Context c) {
m = PreferenceManager.getDefaultSharedPreferences(c);
editor = m.edit();
requestQueue = Volley.newRequestQueue(c);
}
My Question here is: Is there an easy way I can "wait" for the answer from volley so I can continue to work with the response that I get?
Edit 1:
I now added an interface and changed the code around to this:
getString(new VolleyCallback() {
#Override
public void onSuccess(String result) {
getPiecesDTOFromJSON(result);
}
}, searchURLBuilder);
return globalPieceDTOList;
}
private void getString(final VolleyCallback callback, String searchUrl){
StringRequest stringRequest = new StringRequest(Request.Method.GET, searchUrl,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
callback.onSuccess(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Error!!:" + error.getMessage(), "");
}
});
requestQueue.add(stringRequest);
}
Since I cant get the values out of my inner classes, I did a nasty hack and created a global list for my DTO's. The problem now is that "return globalPieceDTOList" is always Null. And again - I would need to "wait" for the Volley response.
Volley requests are async, so when you try to return a value, the request is likely not done yet. If you want to return values from a Volley request use callback interfaces.
Example
public void getString(final VolleyCallback callback) {
StringRequest strReq = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// do some things here
callback.onSuccess(<PASS STRING RESULT HERE>);
}
});
}
public interface VolleyCallback{
void onSuccess(String result);
}
Example usage:
public void onResume(){
super.onResume();
getString(new VolleyCallback(){
#Override
public void onSuccess(String result){
//do stuff here with the result from the volley request
}
});
}
I want to execute JSON_requestarray in my android app but its not working, here is the code:
I want to extract the contents from the array which my PHP returns as a Json_encoded array.. but every time I run it returns null
JsonArrayRequest does not support POST method.
JsonArrayRequest req = new JsonArrayRequest("http://url", new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
Log.d("response", jsonArray.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
});
If the log "response" isn't correct maybe the problem is your web service.
public void doMySearch(List<String> IDs) {
for (String Id : IDs) {
String url = "http://api.tvmaze.com/shows/" + Id + "?embed=nextepisode";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, (String) null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println("ONREQUEST ");
try {
String name = response.getString("name");
String airdate = response.getJSONObject("_embedded").getJSONObject("nextepisode").getString("airdate");
HashMap<String, String> episodesToDisplay = new HashMap<String, String>();
episodesToDisplay.put(name, airdate);
listOfEpisodes.add(episodesToDisplay);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
System.out.println("BEFORE ADD TO REQUEST QUEUE ");
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
System.out.println("AFTER ADD TO REQUEST QUEUE ");
}
System.out.println("AFTER FOR LOOP ");
}
See my prints in the code, the output I get with 4 items in my IDs list is:
BEFORE ADD TO REQUEST QUEUE
AFTER ADD TO REQUEST QUEUE
BEFORE ADD TO REQUEST QUEUE
AFTER ADD TO REQUEST QUEUE
BEFORE ADD TO REQUEST QUEUE
AFTER ADD TO REQUEST QUEUE
BEFORE ADD TO REQUEST QUEUE
AFTER ADD TO REQUEST QUEUE
AFTER FOR LOOP
ONREQUEST
ONREQUEST
ONREQUEST
ONREQUEST
The point is System.out.println("AFTER FOR LOOP "); is executed before onRequest and I want it to call a function in that place which would use a list populated inside onRequest. I thought onRequest would be executed after adding items to queue but it's not. Is there any way I can make it work in the order I expect? I cannot call funtion inside onRequest since I want it to use fully populated list and onRequest is called many times at once.
You have to create a callback to it.
Like this
public interface VolleyCallback {
void onSuccess(String string);
void onFailure(VolleyError error);
}
Then when you call your doMySearch function, you pass your callback, like this:
doMySearch(ids, new VolleyCallback() {
#Override
public void onSuccess(String response) {
Log.d("Success", response);
}
#Override
public void onFailure(VolleyError error) {
Log.e("Error", "ops thats an error!");
}
});
And finally, on your doMySearch function, where you override the onResponse and onErrorResponse listener you call your callback, like this:
public void doMySearch(List<String> IDs, final VolleyCallback callback) {
for (String Id : IDs) {
String url = "http://api.tvmaze.com/shows/" + Id + "?embed=nextepisode";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, (String) null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
System.out.println("ONREQUEST ");
callback.onSuccess("ONREQUEST");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
callback.onFailure(error);
}
});
System.out.println("BEFORE ADD TO REQUEST QUEUE ");
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
System.out.println("AFTER ADD TO REQUEST QUEUE ");
}
System.out.println("AFTER FOR LOOP ");
}
Your code block is executed async, so you have to put your code inside the onResponse method.
Here's my layout code;
static String userLocation(String url) {
RequestQueue queue = Volley.newRequestQueue(context);
// String url = "http://www.jobdiagnosis.com/iphone/userlocation.php";
StringRequest dr = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
res=response;
//edit_location.setText(response);
// Toast.makeText(context, response, Toast.LENGTH_LONG).show();
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error.
Toast.makeText(getApplicationContext(), "error"+error, Toast.LENGTH_LONG).show();
Log.d("error", ""+error);
}
}
);
queue.add(dr);
return res;
}
When I toast the response on same method then response prints fine
and when I call method and print return statement then res prints null.
Any help is appreciated. Thank you in advance.
Please suggest me how we can share response within a one or more activity
And sorry for my bad English..
this is an asynchronous request, the volley processes the request in background thread and delivers the response in onResponse()
if you're looking for synchronous response try this
Try to declare res like global variable. Not return value. Because you didn't know, when request will finished. And use this global variable.