Как устранить утечку памяти в ответе на залп для фоновой службы

Я использую этот сервис для отправки местоположения в веб-базу данных с помощью Volley. Я боролся с утечкой памяти почти две недели, но так и не смог ее решить. Я просмотрел все связанные вопросы, но не смог найти рабочего решения.

Когда служба работает в фоновом режиме, она отправляет местоположение с помощью Volley, а использование оперативной памяти в Устройстве продолжает увеличиваться с каждым отправленным запросом, пока не произойдет сбой из-за OutOfMemory или система не завершит процесс. Я попытался удалить кеш, попытался сделать службу удаленным процессом, чтобы он мог очищать память процесса при перезапуске и многое другое, но пока не смог решить эту проблему, и я умираю здесь, чтобы решить ее. Если кто-нибудь может мне помочь, я очень ценю это. Спасибо

Итак, вот мой код:

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)

}    

ОтправитьКоординаты в базу данных:

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

}

person Psycho    schedule 26.07.2019    source источник


Ответы (1)


Зачем вы создаете новые очереди запросов? Очередь запросов должна быть одноэлементной для каждого приложения. Если вы создаете новый каждый такой запрос, у вас будет ужасная производительность и куча ненужных потоков. Это, вероятно, ваша проблема.

person Gabe Sechan    schedule 26.07.2019
comment
Это было мужчиной. Извините за недостаток знаний, я новый разработчик Android. Задача решена. Сохрани меня в своих молитвах. Большое спасибо, чувак... @Gabe Sechan - person Psycho; 26.07.2019