In a recent webinar, we welcomed Olivier Le Goaër, Associate professor at Université de Pau et des Pays de l’Adour (Pau, France), to discuss greenIT for mobile applications (replay is available in French here). Indeed, Olivier started in 2019 to work on a project to make native mobile apps more sustainable, environmentally, and socially acceptable.

He aims to build a repository of best practices for developers that can be detected in the source code so they’re all actionable and low-level. So he voluntarily excluded rules and best practices that can’t be detected, for instance, if they’re too high level. At this date (Feb 2023), this knowledge base only targets Android, but an announcement was made about iOS support, meaning new rules will come on iOS. He came up with a repository of 42 coding rules.

Note: make sure register to our next live sessions for more best coding practices.

Overview of the best practices for sustainable Android apps

To provide insights into the content of this repository, let’s browse some of the code smells you might find in your Android code.

Tune Constrained Workers

You can request tasks to be executed in the app with the WorkRequest class:

					WorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(MyWork.class).build();

But we can also use Constraints on these WorkRequest, for instance, to indicate this task should be run only when the device is charging (plugged):

					Constraints constraints = new Constraints.Builder().setRequiresCharging(true).build();
WorkRequest myWorkRequest = new OneTimeWorkRequest.Builder(MyWork.class).setConstraints(constraints).build();

It allows delaying computations for later when it makes sense and so sparing energy.

Fused Location API


The Android API provides services to get the GPS coordinates of a device, and listens for regular updates of their values:

					import android.location.LocationManager;

LocationManager locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);

But there exists an alternative with an API maintained by Google, claimed to be less consuming:


FusedLocationProviderClient fusedClient = LocationServices.getFusedLocationProviderClient(this);
fusedClient.requestLocationUpdates(mRequest, mCallback, null);

Don’t be too greedy on frame rate

Frame rate has a direct impact on energy consumption. 60 fps is the default value, so be careful no putting a value higher if it’s not relevant:

					Surface s = mySurfaceView.getHolder().getSurface();

In case it’s acceptable for you, decrease this value to 30 for instance:


Don’t Ignore Battery Optimizations

Android has native smart mechanisms to optimize battery consumption. So unless you have good reasons, we should not ask permission to ignore them:


Don’t keep the screen ‘on’

By default, your OS will turn the screen off when users get idle with their devices. You can tune your Android app to always keep the screen on, but this will have a tremendous impact on the battery, so you should avoid it if your context allows it:

					<RelativeLayout xmlns:android=""
    android:keepScreenOn="true"> <!-- avoid this -->

Avoid sensor leaks

You can register to a sensor to listen to its values (such as the Accelerometer):

					sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, 20000);

But it’s important not to forget to unregister; otherwise, your app will continue to receive and compute data even in the background. So to avoid this, you need to unregister:


Sensor Coalesce

Similar to the previous example, when calling the registerListener method:

					sensorManager = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE);
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometer, 20000);

You can choose to overload the call with a 4th parameter called maxReportLatencyUs:

					sensorManager.registerListener(this, accelerometer, 20000, 190000);

The documentation describes this as the “Maximum time in microseconds that events can be delayed before being reported to the application. A large value allows reducing the power consumption associated with the sensor”. A value of 0 means calling the first method above. Think of sending events as a single batch instead of multiple small batches.

Avoid wide version range

To avoid “software obesity”, meaning embedding too many unnecessary components, you should try to restrict the version ranges of the SDK versions:

					android {
  defaultConfig {
    applicationId “"
    minSdkVersion 7
    targetSdkVersion 23
    versionCode 1
    versionName “1.0”

Favor WebP images

This one is not Android-specific but concerns almost all mobile applications that embed images. WebP is an optimized format that should be favored for every image.

					$> ls

			background.png => prefer background.webp
			logo.jpeg => prefer logo.webp

Share your GreenIT practices

This knowledge base of best practices can be theoretically implemented in static analysis tools. For instance, an implementation called ecoCode Mobile exists for SonarQube., if you want to give it a try. This catalog is also available on our public Hub of best practices, and can be used in Promyze.

If, in your context, greenIT is a significant concern and your organization aims at raising developers’ skills on that topic, Promyze can be an excellent alley to centralize and share your best greenIT practices in your context.

Also, make sure register to our next live sessions for more best coding practices.

Start connecting developers' knowledge with Promyze

Best coding practices shared from IDEs & Code reviews.

Promyze, the collaborative platform dedicated to improve developers’ skills through best practices sharing and definition.

Crafted from Bordeaux, France.

©2023 Promyze – Legal notice