When I deployed a new version Android application to client's UAT environment, the client reported background jobs did not run at all. I did not the why the background jobs did not run at all. I had checked the jobs did run in development environment.
After some troubleshooting, client reports they have upgrade the devices from 7.1.1 to 8.1. However, this did not seems to be the problem as I had tested devices with Android 8.1 in development environment. After more troubleshooting, client reported the previous version application also not work in UAT environment. So the problem must be either Android 8.1 or the some environment changed.
Connected network does not means any connected networks
In order to find out the root cause of the problem, I digged into the source code of WorkManager
. And I found out the following code:
/**
* A {@link ConstraintController} for monitoring that any usable network connection is available.
* <p>
* For API 26 and above, usable means that the {@link NetworkState} is validated, i.e.
* it has a working internet connection.
* <p>
* For API 25 and below, usable simply means that {@link NetworkState} is connected.
*/
public class NetworkConnectedController extends ConstraintController<NetworkState> {
public NetworkConnectedController(Context context, TaskExecutor taskExecutor) {
super(Trackers.getInstance(context, taskExecutor).getNetworkStateTracker());
}
@Override
boolean hasConstraint(@NonNull WorkSpec workSpec) {
return workSpec.constraints.getRequiredNetworkType() == CONNECTED;
}
@Override
boolean isConstrained(@NonNull NetworkState state) {
if (Build.VERSION.SDK_INT >= 26) {
return !state.isConnected() || !state.isValidated();
} else {
return !state.isConnected();
}
}
}
Apparently the implementation mentions that it also checks the validity of network for API 26 and above. However, it is not mention in the documentation.
Any working network connection is required for this work.
As client's UAT environment does not allow internet, it is not a valid network. Thus, the background jobs that set to require connected network will not run.
Work around the problem
If you look into the implementation of other NetworkType
, they do not the check the validity of network. (Then, why is it only checked in NetworkType.CONNECTED
). You can use NetworkType.UNMETERED
or others if you can assume it is only used certain kind of network. Otherwise, you have to implemnt it yourself.
I have created a issue on tracker. Hopefully, Google will provide a separate option to check the validity of a network.