'Android application works with debugger but not in release mode

I have been trying to implement a debouncer for my application, I am trying to reduce requests to the server using this debouncer, eventually, I managed to implement the debouncer but, it seems to work only when I am using the debugger to debug the app.

This is how I implemented the debugger

public class NewDebouncedRunnable implements Runnable {

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    private final Runnable operation;
    private final long delayMillis;
    private ScheduledFuture<?> scheduledFuture;

    private long lastRunTime = -1;
    private boolean isQueued = false;
    private Context context;

    public NewDebouncedRunnable(Context context,Runnable operation, String name, long delayMillis) {
        this.operation = operation;
        this.delayMillis = delayMillis;
        this.context = context;
    }

    public void synchronized run() {

        if(lastRunTime==-1){
            Toasty.success(context,"LastRunTime reset",0).show();
        }

        long currentTime = getCurrentTimeMillis();

        System.out.println(currentTime-lastRunTime);

        if (shouldRunNow(currentTime)) {
            // we've never called this before, call it now
            System.out.println("Registered");
            lastRunTime = currentTime;
            operation.run();
        } else {
            System.out.println("Queued");
            if(scheduledFuture!=null){
                scheduledFuture.cancel(true);
            }
            schedule(this::scheduledRun, delayMillis);
        }
    }

    private void scheduledRun() {
        Log.d("SCHEDULED RUN","running scheduled task");
        lastRunTime = getCurrentTimeMillis();
        isQueued = false;
        operation.run();
    }

    private boolean shouldRunNow(long currentTime) {
        return currentTime-lastRunTime > delayMillis;
    }

   
    private void schedule(Runnable call, long delayMillis) {
        scheduledFuture = scheduler.schedule(call, delayMillis, TimeUnit.MILLISECONDS);
    }

  
    long getCurrentTimeMillis() {
        return System.currentTimeMillis();
    }
}

This is my Debounced Runnable instance

 NewDebouncedRunnable increaseOrderItemDebounce = new NewDebouncedRunnable(context,new Runnable() {
            @Override
            public void run() {
                try{
                    Log.d("DEBOUNCE","Debounced run");
                    
                    HelperClass.getInstance().updateOrderItem(context, item, item.getQuantity(), new HelperClass.ResponseListener<ResponseAddUpdateToCart>() {
                        @Override
                        public void onSuccess(ResponseAddUpdateToCart response) {
                            Toasty.success(context,"Cart Updated", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onFailure(String error) {

                        }
                    });

                 
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            }
        },"",20000);

This is how I set my onClickListener for the button

 holder.btnPlus.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                item.setQuantity(item.getQuantity()+1);
                increaseOrderItemDebounce.run();
            }
        });

I should also note that the button is part of a recycler view, after making a successful request to the server, the adapter is notified that items have changed using adapter.notifyItemRangeChanged()like this

if (orderListAdapter != null && orderlistRview.getLayoutManager() != null) {
                Parcelable recyclerViewState = orderlistRview.getLayoutManager().onSaveInstanceState();
      
                orderlistRview.getLayoutManager().onRestoreInstanceState(recyclerViewState);
         
                orderListAdapter.notifyItemRangeChanged(0,orderListAdapter.getItemCount());

            }

The main issue I am facing here is that every time I click the button in regular mode the lastRunTime variable is reset, resulting in continuous requests to the server but when I am running the app using a debugger and setting breakpoints, it is working as it is intended to.



Solution 1:[1]

try this in Gradle.build

buildTypes {

    release {

        **debuggable true** 

        minifyEnabled false

        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

    }

}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 user8120547