which way is better in android , JobScheduler or use timer?

Viewed 872

I'm developing a chat application, For getting new messages in real-time we use a foreground service. (because of some situation we can't use FCM) To be confident that clients are connected to the server, We send a ping to server every 1 minute with JobScheduler. Now we have a battery usage problem. It's better to use CountDownTimer like bellow code in our foreground service :

CountDownTimer countDownTimerPingPeriodic;
public static boolean isPinging;

public void pingPeriodic(boolean fromService) {

    if (countDownTimerPingPeriodic != null) {
        countDownTimerPingPeriodic.cancel();
        countDownTimerPingPeriodic = null;
    }


    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            long future = 75000;
            countDownTimerPingPeriodic =

                    new CountDownTimer(60000, 60000) {

                        @Override
                        public void onTick(long l) {

                        }

                        @Override
                        public void onFinish() {
                            sendPing(false);
                            pingPeriodic(false);

                        }
                    };
            isPinging = true;
            countDownTimerPingPeriodic.start();

        }
    });

}

or it's better to use job service like bellow (Now we use bellow code and send ping in onStartJob):

public class ScheduleConnectionJob extends JobService {

private static final String TAG = "ScheduleConnectionJob";
private int i = 0;

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return Service.START_STICKY;
}

@Override
public boolean onStartJob(JobParameters params) {

    //here I will send a ping to the server

    jobFinished(params, true);
    Util.scheduleJob(getApplicationContext()); // reschedule the job
    return true;
}

@Override
public boolean onStopJob(JobParameters params) {
    Util.scheduleJob(getApplicationContext());
    return true;
}

@Override
public void onDestroy() {
    super.onDestroy();
    Util.scheduleJob(getApplicationContext());
}}

And to call and repeat this service We use bellow code to repeat every 1 minute:

public class Util {

public static final long MinimumSchadulePeriodic = 15 *  60 * 1000 ;
// schedule the start of the service every 10 - 30 seconds
public static void scheduleJob(Context context) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        ComponentName serviceComponent = new ComponentName(context, ScheduleConnectionJob.class);

        JobInfo.Builder builder = new JobInfo.Builder(0, serviceComponent);

        FileLog.i("Util:",
                Thread.currentThread().getStackTrace()[2].getLineNumber() + " " +

                        "scheduleJob:scheduleJob");
        builder.setMinimumLatency(MinimumSchadulePeriodic); // wait at least
        builder.setOverrideDeadline(60 * 1000); // maximum delay

        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY); // require unmetered network

        JobScheduler jobScheduler = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE);

        if (jobScheduler != null) {
            jobScheduler.schedule(builder.build());
        }
    }
}}
2 Answers

If you don't support below SDK 14 you can use workmanager. Otherwise see this guide to read about all the options.

Some extra resources on battery management: Doze and standby, power management restrictions, Analyzing power usage, Excessive wake-ups, Excessive network usage in background

Hope this helps you along a bit. I have to say that having your app ping the backend every minute seems a bit much. Unless its vital that your users receive their messages the instant they get send, it might be better to atleast bump that down to 5 or 10 minutes in background.

Related