I Want to Store the response of Volley in a Public variable but when I Toast it out the volley request that returns null
public JSONArray array ;
String URL = "http://192.168.1.104/json.php";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
array = new JSONArray();
JsonArrayRequest request = new JsonArrayRequest( URL,new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
array = response;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(this).add(request);
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
As people have said, calling the Toast initiation within onResponse() works, but the best way to handle this is to create a small listener interface or method that is called in onResponse and implemented where you need it.
I'd also strongly suggest only passing the data you need and saving that in a model class, rather than just saving the response outright.
a very simple example would be
String URL = "http://192.168.1.104/json.php";
// make sure your class implements this
public interface ResponseListener {
public gotResponse(JSONArray array);
}
// implementation of ResponseListener
public gotResponse(JSONArray array) {
// eventually do more with this data
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_json);
ResponseListener listener = this;
JsonArrayRequest request = new JsonArrayRequest( URL,new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
listener.gotResponse(response);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Volley.newRequestQueue(this).add(request);
One way could be moving the line:
Toast.makeText(json.this, array.toString(),Toast.LENGTH_LONG).show();
exactly to the line after: array = response;
Related
I have written a small program using JsonObjectRequest to get the data from an API, but I've got the result but I can't use it outside the function. Can anyone help me about it? I've got stuck here for 5 days already. When I want to use response data outside of this, it always show the token is null.
Here's my code.
RequestQueue requestQueue1=Volley.newRequestQueue(this);
JsonObjectRequest objectRequest1=new JsonObjectRequest(
Request.Method.GET,
urlToken,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
parseJson(response);
try {
token=response;
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue1.add(objectRequest1);
Using interface call back could be a solution: Code looks like :
interface TokenCallback {
void onTokenReceived(String token);
void onDataReceived(String responseData);
}
private void makeApiCall(String url,String token,Boolean isGetRequest,TokenCallback tokenCallback){
RequestQueue requestQueue1=Volley.newRequestQueue(this);
// put if else to adjust GET or POST request
if (isGetRequest){
// prepare Get request
}else {
// Prepare post request
}
JsonObjectRequest objectRequest1=new JsonObjectRequest(
Request.Method.GET,
url,
token,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
parseJson(response);
try {
// Parse token here
if (response.has("token")){
tokenCallback.onTokenReceived(token);
}else {
tokenCallback.onDataReceived(response.toString());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
requestQueue1.add(objectRequest1);
}
Call above method where you are starting API call like below:
makeApiCall("https://your.api.url",null,true,new TokenCallback() {
#Override
public void onTokenReceived(String token) {
if(!token.isEmpty()){
// use token
makeApiCall("https://your.api.url",token,false,new TokenCallback() {
#Override
public void onTokenReceived(String token) { }
#Override
public void onDataReceived(String responseData) {
// Parse your json response data here......
}
});
}
}
#Override
public void onDataReceived(String responseData) {
}
});
I want to see my array list in my logcat but when I run my app in logcat it shows that size of my array list is zero and there is no elements in it
this is my activity
public class Tmp2 extends AppCompatActivity {
public RequestQueue queue;
static ArrayList<Question> array_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tmp2);
array_list = new ArrayList<>();
queue= AppController.getInstance(this).getRequestQueue();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
"https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json",
(JSONArray) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i=0;i<response.length();i++) {
try {
Question question = new Question();
question.setAnswer(response.getJSONArray(i).get(0).toString());
question.setAnswertrue((Boolean) response.getJSONArray(i).get(1));
array_list.add(question);
} catch (JSONException e) {
e.printStackTrace();
}
}Log.d("wakwash","array "+array_list.size());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
Log.d("json","array "+array_list.size());
queue.add(jsonArrayRequest);
Log.d("json","array "+array_list);
}
}
Logcat:
2020-10-25 00:32:43.548 18576-18576/com.example.practice D/json: array 0
2020-10-25 00:32:43.548 18576-18576/com.example.practice D/json: array []
its showing that size of my array is zero and there is no element it but when i use this log in onResonse it gives sizeand elements both. How can I access my array list out of the response
This is because you are logging your array size at wrong place even before you're getting the response, you are making a call which is asynchronous but the log that you've written is executed in synchronous manner that will always be empty.
Log your data when your response is received i.e in onResponse callback.
public class Tmp2 extends AppCompatActivity {
public RequestQueue queue;
static ArrayList<Question> array_list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tmp2);
array_list = new ArrayList<>();
queue= AppController.getInstance(this).getRequestQueue();
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET,
"https://raw.githubusercontent.com/curiousily/simple-quiz/master/script/statements-data.json",
(JSONArray) null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for(int i=0;i<response.length();i++) {
try {
Question question = new Question();
question.setAnswer(response.getJSONArray(i).get(0).toString());
question.setAnswertrue((Boolean) response.getJSONArray(i).get(1));
array_list.add(question);
} catch (JSONException e) {
e.printStackTrace();
}
}Log.d("wakwash","array "+array_list.size());
// Log it over here
Log.d("json","array "+array_list.size());
Log.d("json","array "+array_list);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
//Log removed from here
queue.add(jsonArrayRequest);
}
}
You have to do your work after the response is received rather than doing it outside of the response scope, You can also make a callback for your response.
public class BtcPaymentQR extends AppCompatActivity {
ImageView QrCode;
RequestQueue mQueue;
public static String btcAddress = "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_btc_payment_qr);
QrCode = findViewById(R.id.imageViewQR);
mQueue = Volley.newRequestQueue(this);
getAddress();
Log.i("test", "onCreate: " + btcAddress);
}
public void getAddress(){
String url = "xxx"
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject jsonObject = response.getJSONObject("address");
String a = jsonObject.getString("extkey_next_receiving_address");
BtcPaymentQR.btcAddress=a;
Log.i("test", "onResponse: " + btcAddress);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
mQueue.add(request);
}
Logcat
My Question is, How do I get the value of "a" from the method. I've tried everything to save it in another global variable, with return, with get and set.
I need the value to use it in a other Method
Your problem is solved by using static variable to save response,and static variables are part of class not object so you can use static variable with class name like MainActivity.myValue in my example.
Your Activity or Fragment Class:
MainActivity Extends AppCompatActivity{
public static String myValue="";
//define this in your classs where you run the web service
}
your response method
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject jsonObject = response.getJSONObject("address");
String a = jsonObject.getString("extkey_next_receiving_address");
MainActivity.myValue=a;
Log.i("test", "onResponse: " + MainActivity.myValue);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i("test2", "onErrorResponse: error");
}
});
mQueue.add(request);
}
Simple way is using static variable. define a static variable for class and assign the value of 'a' to this static variable and use it every where.
I just want to wait in a splash screen until my JSON is processing, but that is not happening. TheonPostExecute() method is executed just after doinbackground(). There is no time to load the whole JSON.
Here is my code. I am getting List size zero first then JSON will start to load.
private class GetContacts extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
datalist = new ArrayList<>();
Log.e("entering","Enter Inside");
try{
JsonArrayRequest billionaireReq =
new JsonArrayRequest(new ApiURLs().getAll_movies_url()
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Log.e("response", "Response" + response);
//Initialize Gson obj to process jason response
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
// assigning data in model class, we initializing this class as a array type
// because the response is in array format
HomeModel[] getResult = gson.fromJson(response.toString(), HomeModel[].class);
// this loop help us in fetching all the records of model class
for (int i = 0; i < getResult.length; i++) {
Log.e("response", "Model Values" + getResult[i].toString());
//datalist.add(getResult[i]);
datalist.add(getResult[i]);
}
//GlobalData.setGlobal_movie_list(datalist);
Log.e("DataLoded","Record Added");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Request","Error" + error);
}
});
//This is a queue which is used by Volley to lineup requests
AppController.getInstance().addToRequestQueue(billionaireReq);
}
catch (Exception e){
Log.e("Error","Error"+e);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Log.e("Data","DataSize"+datalist.size());
}
}
I'm trying to use Volley as a DBA layer to call a webservice that hadles JSON objects. Because this layer is below the activity and another service layer, it doesn't seem to be working properly. I'll try to explain my setup:
MainActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ProductService productService = new ProductService();
productService.getProduct();
}
ProductService.java:
public void getProduct() {
JsonObjectRequest req = new JsonObjectRequest("http://echo.jsontest.com/name/Milk/price/1.23/", null, createMyReqSuccessListener(), createMyReqErrorListener());
ApplicationController.getInstance().addToRequestQueue(req);
}
private Response.Listener<JSONObject> createMyReqSuccessListener() {
return new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.v("response", response.toString());
}
};
}
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
return;
}
};
}
I hope that is clear enough.
In the end, I would like to use the ProductService::getProduct() from an activity and the the actual JSON response from the webservice in a variable which I can later use.
However, at the moment, the line
Log.v("response", response.toString());
doesn't even execute. What am I doing wrong?
What I would try is this:
Declare getProduct as
public void getProduct(Response.Listener<JSONObject> listener,
Response.ErrorListener errlsn) {
JsonObjectRequest req = new JsonObjectRequest("http://echo.jsontest.com/name/Milk/price/1.23/",null, listener, errlsn);
ApplicationController.getInstance().addToRequestQueue(req);
}
And than call in your activity like this:
productService.getProduct(
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
variableFromActivity = response;
//Or call a function from the activity, or whatever...
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Show error or whatever...
}
});
Create an abstract class AppActivity
import androidx.appcompat.app.AppCompatActivity;
public abstract class AppActivity extends AppCompatActivity
{
abstract void callback(String data);
}
Extend all your Activities using AppActivity
public class MainActivity extends AppActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String url = "Your URL";
JSONObject jsonBody = new JSONObject();
try {
jsonBody.put("Title", "Android Volley Demo");
jsonBody.put("Author", "BNK");
}
catch (JSONException e) {
System.out.println(e);
}
final String requestBody = jsonBody.toString();
Messenger messenger = new Messenger(MainActivity.this);
messenger.sendMessage(this, url, requestBody);
}
public void callback(String data)
{
System.out.println(data);
}
}
Create Messenger class as below:
public class Messenger
{
private AppActivity myActivity;
public Messenger(AppActivity activity)
{
myActivity = activity;
}
public void sendMessage(Context context, String url, final String requestBody)
{
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(context);
// Request a string response from the provided URL.
StringRequest stringRequest =
new StringRequest(
Request.Method.POST,
url,
null,
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error);
}
}
) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
}
catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
myActivity.callback(new String(response.data));
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
queue.add(stringRequest);
}
}
Hope it helps.