How to access response value out of OnResponse method? - java

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.

Related

can't return an arraylist of objects, coming from a network call

Hi everyone I am a student and I am starting to learn Android. I have a problem with a method, I can't create a method that returns me an ArrayList . After making a network call and adding the users resulting from the network call to the arrayList, I can't get the method to return the arrayList of all the users downloaded from the network call. My code is:
public class Utils {
static final ArrayList<User>u1 = new ArrayList();
public static ArrayList<User> getUserPicture(String uid,Activity activity) {
RequestQueue requestQueue = Volley.newRequestQueue(activity);
JSONObject jsonfinal = new JSONObject();
String url_getProfile = "https://ewserver.helpme/helpme.php";
try {
jsonfinal.put("uid", uid);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest
jsonObjectRequest
= new JsonObjectRequest(
Request.Method.POST,
url_getProfile,
jsonfinal,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
String picture=response.getString("picture");
u1.add(new User
(uid,picture));
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
MainActivity.requestQueue.add(jsonObjectRequest);
return u1;
}
}
Now if i call:
ArrayList<User> user=getUserPicture(uid,activity);
Log.d("main_activity_usersize",String.valueOf(user.size()));
i get empty arraylists [].Why?how can I return the arraylist to the method?

How to store response in a variable in Volley?

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;

Java Json Request Android

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.

Android Async Tsk not Executing Properly

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());
}
}

Adapter.notifyDataSetChanged() not working inside onCreate()

I am trying to parse JSON using Volley.
I am using a vector to store parsed data and calling adapter.notifyDataSetChanged() inside onCreate() after filling vector. But no changes are there.
If I am calling adapter.notifyDataSetChanged() inside try-catch block of getData() then it is working fine. Why?
public class MainActivity extends AppCompatActivity{
Vector<Data> ve;
private Adapter adapter;
RecyclerView recyclerView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=(RecyclerView)findViewById(R.id.main_recycler_view);
ve=new Vector<Data>();
adapter=new Adapter(ve);
RecyclerView.LayoutManager lm=new LinearLayoutManager(getApplicationContext());
recyclerView.setLayoutManager(lm);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setAdapter(adapter);
getData(ve);
adapter.notifyDataSetChanged(); //not working
}
public void getData(final Vector<Data> ve)
{
String url = "https://api.androidhive.info/contacts/";
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String jsonString) {
try
{
JSONObject object = new JSONObject(jsonString);
JSONArray arr = object.getJSONArray("contacts");
int len=arr.length();
JSONObject obj;
for (int i = 0; i < len; i++)
{
obj = arr.getJSONObject(i);
ve.add(new Data(obj.getString("name"), obj.getString("email"));
}
//adapter.notifyDataSetChanged();working
}
catch (JSONException e)
{
Toast.makeText(getApplicationContext(),"JSON Parsing Exception",Toast.LENGTH_LONG);
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getApplicationContext(), "Some error occurred!!", Toast.LENGTH_SHORT).show();
}
});
RequestQueue rQueue = Volley.newRequestQueue(this);
rQueue.add(request);
}
}
you cannot do that reason nothing volley used network requests which are designed to be asynchronous in nature , so the network request is put in queue and code continues to execute the notifyadapter changed method . The response to the network call occurs afterwards and add data, you should call that method after data is received by calling it inside volley on response method

Categories