JobScheduler

Beginning with Android Lollipop, JobScheduler is able to schedule tasks with complex conditions and execute them when those conditions are met. Consider FirebaseJobDispatcher instead for greater backwards compatibility.

JobScheduler js = (JobScheduler) context.getSystemService(Context.JOB_SCHEDULER_SERVICE); // Get a JobScheduler
JobInfo job = new JobInfo.Builder( // Build a new JobInfo object
  MY_BACKGROUND_JOB, new ComponentName(context, MyJobService.class)) // Point to your JobService class
    .setRequiredNetworkType(JobInfo.NETWORK_TYPE_UNMETERED) // Only trigger when on an unmetered network e.g. Wifi
    .setRequiresCharging(true) // Only trigger when being charged
    .setBackOffCriteria(TWO_MINUTES,BACKOFF_POLICY_EXPONENTIAL) // After first fail, wait 2 minutes, and increase wait time exponentially with every subsequent fail
    .setMinimumLatency(FIFTEEN_MINUTES) // Minimum wait before triggering is 15 minutes
.build();

js.schedule(job) // Call the job using this code

Foreground Services

A foreground service is a service that the user is actively aware of because Android requires it to post a non-dismissable ongoing notification. They are typically used to show the user the real-time progress of a long-running operation. Allows the user to perform basic interactions with your service. Examples would be playback controls in a music app or Google Maps navigation instructions.

Android will prioritise these even if the system is memory constrained.