Reputation: 1012
I am using this service to send location to a web database using Volley. I have been fighting with Memory Leaks for almost two weeks but still couldn't solve it. I went through all the related questions but could not find working solution.
When the service is running in the background, it sends location using Volley and the Ram usage in the Device keeps increasing with each request sent untill it craches for OutOfMemory or the system kills the process. I tried deleting cache, tried making the service as a remote process so that it may clear process memory when restarts and many things but could not solve it yet and i'm dying here to solve it. If anyone could help me, I really appreciate it. Thanks
So, Here is my code:
ForeGroundService:
public int onStartCommand(final Intent intent, int flags, final int startId) {
//Log.i(TAG,"onStartCommand");
sessionManager = new SessionManager(ForeGroundService.this);
sessionManager.checkLogin();
if (sessionManager.isDayRunning().equals("1") && serviceStarted == 1)
if (!mGoogleApiClient.isConnected()) mGoogleApiClient.connect();
TimerForServiceDelay = new CountDownTimer( 5 * 60 * 1000, 60*1000) {
@Override
public void onTick(long l) {
//Log.i(TAG,"onTick (onStartCommand)");
}
@Override
public void onFinish() {
//Log.i(TAG,"onFinish (onStartCommand)");
String Location = "Location :: [" + Co_or[0] + "," + Co_or[1] + "]";
Intent notificationIntent = new Intent(ForeGroundService.this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(ForeGroundService.this, 0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(ForeGroundService.this, LOCATION_SENDING_NOTIFICATION_CHANNEL_ID)
.setContentTitle("Service")
.setContentText(Location) .setColor(getResources().getColor(R.color.colorPrimary))
.setSmallIcon(R.drawable.ic_my_location_black_24dp)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.build();
SendCoordinatesToDatabase();
if (sessionManager.isDayRunning().equals("0")) {
mGoogleApiClient.disconnect();
Log.i(TAG, "just before stop self");
serviceStarted = 0;
stopSelf();
} else {
//Log.i(TAG,"on else condition of stop self");
ContextCompat.startForegroundService(getApplicationContext(), new Intent(ForeGroundService.this,ForeGroundService.class));
startForeground(1, notification);
//stopForeground(true);
}
stopSelf();
}
}.start();
return Service.START_STICKY; //This allows to restart the service when get killed automatically (WORKING solution)
}
SendCoordinatesToDatabase:
public void SendCoordinatesToDatabase() {
final String URL_LOCATION = getResources().getString(R.string.URL_LOCATION);
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_LOCATION, new Response.Listener<String>() {
@Override
public void onResponse(String response) {
Log.i(TAG, "[" + response + "]");
try {
JSONObject jsonObject = new JSONObject(response);
String success = jsonObject.getString("success");
String message = jsonObject.getString("message");
//Log.i(TAG, "[" + message + "]");
if (success.equals("1")) {
// TODO: Do something later
} else {
// TODO: Do something later
}
} catch (JSONException e) {
e.printStackTrace();
Log.i(TAG, "JSON Error : " + e.toString());
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
public Request<?> setCacheEntry(Cache.Entry entry) {
return super.setCacheEntry(null);
}
@Override
public Cache.Entry getCacheEntry() {
return null;
}
@Override
public Request<?> setRequestQueue(RequestQueue requestQueue) {
requestQueue.getCache().clear();
return super.setRequestQueue(requestQueue);
}
@Override
protected Map<String, String> getParams(){
String[] all = collectParameters(row,samityAndBranchDistance);
final String vendor = getVendor();
Map<String, String> params = new HashMap<>();
params.put("email", all[0]);
params.put("lati", all[1]);
params.put("longi", all[2]);
params.put("near_sam_dis",all[3]);
params.put("branch_dis",all[4]);
params.put("loc_name",all[5]);
params.put("vendor",vendor);
return params;
}
};
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(this);
requestQueue.getCache().clear();
requestQueue.add(stringRequest);
}
Upvotes: 0
Views: 228
Reputation: 93668
Why are you creating new request queues? The request queue should be a per app singleton. If you're creating a new one each request like this you will have horrible performance and tons of unneeded threads lying around. That's likely your problem.
Upvotes: 3