I am getting outofmemory exception when calling volley continuousally everytime and getting error at RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
Calling Method every 5 seconds like this.
handlerGetJockyLatLong = new Handler();
runnableJockyLatLong = new Runnable() {
#Override
public void run() {
handlerGetJockyLatLong.postDelayed(runnableJockyLatLong, 10000);
getJockyLatLongFromBackEnd();
}
};
handlerGetJockyLatLong.postDelayed(runnableJockyLatLong, 10000);
Method is:
private void getJockyLatLongFromBackEnd() {
final String getJockyID_URL = getProfileInformationURL(getUserAccessToken(UserSideTrackingPage.this), UserID);
Log.e("getJockyID_URL", getJockyID_URL);
StringRequest request = new StringRequest(Request.Method.GET, getJockyID_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response != null && !response.startsWith("<HTML>")) {
Log.e("getJocky_Url_Responce", response);
//progressDialog.dismiss();
try {
JSONObject jsonObject = new JSONObject(response);
JSONObject jsonObbjectError = jsonObject.getJSONObject("error");
String errorCode = jsonObbjectError.getString("code");
String errorMessage = jsonObbjectError.getString("message");
if (errorCode.equals("0")) {
if (jsonObject.has("data")) {
JSONObject jsonObjectData = jsonObject.getJSONObject("data");
Double latitude = Double.valueOf(jsonObjectData.getString("latitude"));
Double longitude = Double.valueOf(jsonObjectData.getString("longitude"));
globalGoogleMap.clear();
currentLocationMarker = CommonUtils.createMultipleMarkers(globalGoogleMap, latitude, longitude, "Jocky Location", R.drawable.current_location);
PickupLocationMarker = CommonUtils.createMultipleMarkers(globalGoogleMap, Double.valueOf(pickupLat), Double.valueOf(pickupLong), "Pickup Location", R.drawable.pickup_marker_icon);
DropLocationMarker = CommonUtils.createMultipleMarkers(globalGoogleMap, Double.valueOf(dropLong), Double.valueOf(dropLat), "Drop Location", R.drawable.drop_location_marker_icon);
}
} else {
Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("Exception", e.toString());
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Error", error.toString());
}
});
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
queue.add(request);
}
Please tell me i am doing wrong? should not we call always volley? Or should i put volley in singleton class so i can instantiate only once? Any suggestion would be fine. Thanks.
Try to use static RequestQueue here like below given , I experienced the same . When i used static it worked for me .
public class name extends AppCompactActivity{
static RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
public void yourmethod{
//code here
queue.add(request);
}
}
Related
I am trying to get a single integer value with Volley.
In this example the number is 14
In the debugger I get the correct value 14 and assign it to vNumber while in the try/catch block but then when I try to return the vNumber I get value 0 as returned number.
This is the JSON result.
{"result":[{"version":"14"}]}
Here is the code for this function:
int vNumber;
public int getVersionNumber() {
StringRequest stringRequest = new StringRequest(Request.Method.POST, GET_VERSION_NUMBER,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object = new JSONObject(response);
JSONArray jsonArray = object.getJSONArray("result");
JSONObject jsonObject = jsonArray.getJSONObject(0);
vNumber = jsonObject.getInt("version");
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "JSONException: " + e);
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "VolleyError: " + error);
}
});
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
return vNumber;
}
I already tried using sharedPreferences and putting the value inside a textView (the value is correct when I set it in a textView) and then getting it from it but it's still not working. I could create a new table inside my local DB and save the data but it is not necessary in this use case.
Do you have any suggestions on how the return the correct value, and what am I doing wrong here?
Cheers
public void fetchVersionNumber() {
StringRequest stringRequest = new StringRequest(Request.Method.POST, GET_VERSION_NUMBER,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject object = new JSONObject(response);
JSONArray jsonArray = object.getJSONArray("result");
JSONObject jsonObject = jsonArray.getJSONObject(0);
vNumber = jsonObject.getInt("version");
compareAndUpdate(vNumber)
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "JSONException: " + e);
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "VolleyError: " + error);
}
});
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
}
public void compareAndUpdate(int vNumber){
//compare and do your operation
// Get from sharedPref and compare
}
I have two activities, When I will move from activity A to B, B keeps restarting or "refreshing", when i go back from B to A, it also keeps restarting. The code is very big, here I am posting area where I think problem causes :
Thread t = new Thread(new Runnable() {
#Override
public void run() {
while (true) {
deviceStatus();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
this is deviceStatus();
public void deviceStatus(){
try {
RequestQueue requestQueue = Volley.newRequestQueue(InActivate.this);
String URL = "http://gickuwait-dev.com/electionapi/api/DeviceStatus";
JSONObject jsonBody = new JSONObject();
jsonBody.put("device_PK", device_ID2);
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response.equals("true")){
Intent intent = new Intent(InActivate.this, Vote.class);
startActivity(intent);
finish();
}else if(response.equals("false")) {
}
// Toast.makeText(getApplicationContext(), response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#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) {
String responseString;
String json = null;
try {
json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
responseString = String.valueOf(json).trim();
ArrayList<DeviceStatusResponse> list = new ArrayList<DeviceStatusResponse>();
Type listType = new TypeToken<List<DeviceStatusResponse>>() {}.getType();
list = new Gson().fromJson(responseString, listType);
device_Status = list.get(0).getIsActive().toString();
// Toast.makeText(getApplicationContext(), ""+device_Status+" null ", Toast.LENGTH_LONG).show();
return Response.success(device_Status, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
in Activity B, i have the same code to check the device status from the database, any help would be appreciated
You can use Handle to check the repeated task.
private Handler delayHandler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
deviceStatus();
driverDelayHandler.postDelayed(runnable, 1000);
}
};
Don't forgot to cancel on onStop method.
delayHandler.removeCallbacks(runnable);
I build an app, that it load markers in a map, the markers I get it for volley JSON file, but I need that first to load volley, and after continue executing the code, because the other way show me error with latLng null, this parameter is not loaded fast, and another method execute first and show me null.
My volley code for load markers
public void getMarkers(){
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray saagTracker = response.getJSONArray("saagMRK");
for (int i = 0; i < saagTracker.length(); i++) {
JSONObject object = saagTracker.getJSONObject(i);
title = object.getString(TITLE);
snnipet = object.getString(SNNIP);
latLng = new LatLng(Double.parseDouble(object.getString(LAT)), Double.parseDouble(object.getString(LNG)));
coor = coor + "|" + object.getString(LAT) + "," + object.getString(LNG); // Menambah data marker untuk di tampilkan ke google map
addMarker(latLng, title, snnipet);
}
} catch (JSONException e) {
e.printStackTrace();
}
//JSONArray array = new JSONArray(response.body().string());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Ocurrio un error", Toast.LENGTH_LONG).show();
}
});
requestQueue.add(jsonObjectRequest);
}
onCreate it need latLng first for it to can load my geofire parameter
geoQuery = geofire.queryAtLocation(new GeoLocation(latLng.latitude, latLng.longitude),0.1f); // latLng it coming null
You would need to implement a call back for the volley response. A very simple way to do this would be the following.
Step 1: Create this interface
public interface VolleyCallBack {
void onSuccess();
}
Step 2: change your getMarkers() method to this:
public void getMarkers(final VolleyCallBack callBack){
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray saagTracker = response.getJSONArray("saagMRK");
for (int i = 0; i < saagTracker.length(); i++) {
JSONObject object = saagTracker.getJSONObject(i);
title = object.getString(TITLE);
snnipet = object.getString(SNNIP);
latLng = new LatLng(Double.parseDouble(object.getString(LAT)), Double.parseDouble(object.getString(LNG)));
coor = coor + "|" + object.getString(LAT) + "," + object.getString(LNG); // Menambah data marker untuk di tampilkan ke google map
addMarker(latLng, title, snnipet);
callback.onSuccess();
}
} catch (JSONException e) {
e.printStackTrace();
}
//JSONArray array = new JSONArray(response.body().string());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Ocurrio un error", Toast.LENGTH_LONG).show();
}
});
requestQueue.add(jsonObjectRequest);
}
Step 3: Call your getMarkers() method like this:
getMarkers(new VolleyCallBack() {
#Override
public void onSuccess() {
// this is where you will call the geofire, here you have the response from the volley.
geoQuery = geofire.queryAtLocation(new GeoLocation(latLng.latitude, latLng.longitude),0.1f);
});
I am using Volley library to communicate with my database. I use recursive function to check continuously my database but after a period of time seems like the recursive function stop working and I get the following error:
FATAL EXCEPTION: main
Process: com.example.sakis.loginregister, PID: 22637
java.lang.OutOfMemoryError: pthread_create (stack size 131072 bytes) failed: Try again
at java.lang.VMThread.create(Native Method)
at java.lang.Thread.start(Thread.java:1029)
at com.android.volley.RequestQueue.start(RequestQueue.java:145)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:66)
at com.android.volley.toolbox.Volley.newRequestQueue(Volley.java:78)
at com.example.sakis.loginregister.MultiPlayerActivity.func(MultiPlayerActivity.java:342)
at com.example.sakis.loginregister.MultiPlayerActivity$2.onResponse(MultiPlayerActivity.java:160)
at com.example.sakis.loginregister.MultiPlayerActivity$2.onResponse(MultiPlayerActivity.java:133)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:60)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:30)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:99)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5292)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:640)
at dalvik.system.NativeStart.main(Native Method)
I think it is a stackoverflow error when i dont get the proper response in time.Here is the recursive function code that i first call in onCreate method:
void func(){
reject=0;
Response.Listener<String> response1Listener = new Response.Listener<String>() {
#Override
public void onResponse(final String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
request = jsonResponse.getInt("request");
requestorigin = jsonResponse.getString("requestorigin");
category = jsonResponse.getInt("category");
dif_level = jsonResponse.getInt("dif_level");
number_of_questions = jsonResponse.getInt("number_of_questions");
time_of_answer = jsonResponse.getInt("time_of_answer");
if(request==0) {
func();
}
if (request == 1) {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(MultiPlayerActivity.this,R.style.myBackgroundStyle);
alertDialogBuilder.setMessage("Έχεις νέο αίτημα από τον χρήστη " + requestorigin + "\n" + "Κατηγορία Ερωτήσεων: " + array_category[category]
+ "\n" + "Επίπεδο Δυσκολίας: " + array_dif_level[dif_level] + "\n" + "Αριθμός Ερωτήσεων: " + number_of_questions + "\n "
+ "Χρόνος Απάντησης: " + time_of_answer);
alertDialogBuilder.setPositiveButton("Ναι", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface arg0, int arg1) {
Response.Listener<String> response1Listener = new Response.Listener<String>() {
#Override
public void onResponse(final String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
SendResponseRequest sendResponseRequest = new SendResponseRequest(username, response1Listener);
RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
queue1.add(sendResponseRequest);
Response.Listener<String> responseListener=new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success1=jsonResponse.getBoolean("success1");
if(success1) {
Intent intent2 = new Intent(MultiPlayerActivity.this, MultiPlayerGame2Activity.class);
intent2.putExtra("username1",username);
intent2.putExtra("username2",requestorigin);
intent2.putExtra("category", category);
intent2.putExtra("dif_level", dif_level);
intent2.putExtra("number_of_questions", number_of_questions);
intent2.putExtra("time_of_answer", time_of_answer);
intent2.putExtra("level", level);
intent2.putExtra("score", score);
intent2.putExtra("music",music);
intent2.putExtra("sound",sound);
startActivity(intent2);
// android.os.Process.killProcess(android.os.Process.myPid());
finish();
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
Back0Request back0Request = new Back0Request(username,responseListener);
RequestQueue queue = Volley.newRequestQueue(MultiPlayerActivity.this);
queue.add(back0Request);
}
});
alertDialogBuilder.setNegativeButton("Όχι", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Response.Listener<String> response1Listener = new Response.Listener<String>() {
#Override
public void onResponse(final String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
reject = jsonResponse.getInt("reject");
if(reject==1) {
func();
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
RejectRequestRequest rejectRequestRequest = new RejectRequestRequest(username, response1Listener);
RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
queue1.add(rejectRequestRequest);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
} catch (JSONException e)
{
e.printStackTrace();
}
}
};
//text2.setText("OK");
CheckRequest checkRequest = new CheckRequest(username, response1Listener);
/***
int socketTimeout = 30000;//30 seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
checkRequest.setRetryPolicy(policy);
******/
RequestQueue queue1 = Volley.newRequestQueue(MultiPlayerActivity.this);
queue1.add(checkRequest);
//text3.setText("After ");
}
When the variable requests that I take from the database has a zero value I want to check the database again until it will take a non-zero value. Is there any better way to achieve that so I can avoid recursion because it will cause some overflow errors.
Problem solved when i use Singleton Pattern and re-use the same instance of the queue so i prevent out of memory error:
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mContext;
private MySingleton(Context context){
// Specify the application context
mContext = context;
// Get the request queue
mRequestQueue = getRequestQueue();
}
public static synchronized MySingleton getInstance(Context context){
// If Instance is null then initialize new Instance
if(mInstance == null){
mInstance = new MySingleton(context);
}
// Return MySingleton new Instance
return mInstance;
}
public RequestQueue getRequestQueue(){
// If RequestQueue is null the initialize new RequestQueue
if(mRequestQueue == null){
mRequestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
}
// Return RequestQueue
return mRequestQueue;
}
public<T> void addToRequestQueue(Request<T> request){
// Add the specified request to the request queue
getRequestQueue().add(request);
}
I am developing an application using android and i'm trying to get the jSon Array displayed in Listfragment using the loadInBackground() method below in my DataListLoader class:
class DataListLoader extends AsyncTaskLoader<List<Model>> {
List<Model> mModels;
String jsonString;
String name = "Daniel Nyerere", phone = "0652400670";
public DataListLoader(Context context) {
super(context);
loadInBackground();
}
public List<Model> loadInBackground() {
// You should perform the heavy task of getting data from
// Internet or database or other source
// Here, we are generating some Sample data
// Create corresponding array of entries and load with data.
final List<Model> entries = new ArrayList<Model>(50);
StringRequest stringRequest = new StringRequest(
Request.Method.GET, "http://10.0.2.2/webapp/json_get_data.php", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response.trim().contains("server_response")) {
jsonString = response.toString();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
while (count < jsonArray.length()) {
JSONObject jo = jsonArray.getJSONObject(count);
name = jo.getString("name");
phone = jo.getString("user_phone");
entries.add(new Model(name, phone));
System.out.println("DATA FROM JSON ARRAY: " + name + " " + phone);
count++;
return;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = VolleySingleton.getInstance().getRequestQueue();
requestQueue.add(stringRequest);
entries.add(new Model(name, phone));
return entries;
}
But when i try to run it the data from System.out.println("DATA ENTRIES: "+entries); comes as null list ,so no data get displayed in the fragment activity . Anyone who can help me to fix it so that i get data from json because it consume me a lot of time
//You can call it in UI thread
final List<Model> entries = new ArrayList<Model>(5);
StringRequest stringRequest = new StringRequest(
Request.Method.GET, "http://10.0.2.2/webapp/json_get_data.php", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//you need to update the `ListView` content here
//If you need you can create new thread here too e.g. using AsyncTask
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = VolleySingleton.getInstance().getRequestQueue();
requestQueue.add(stringRequest);