- val constraints = Constraints.Builder()
- .setRequiredNetworkType(NetworkType.CONNECTED)
- .build()
- val request = OneTimeWorkRequestBuilder<MyWorker>()
- .setConstraints(constraints)
- .build()
ここで TooManyRequestsException が起こったときに、Coil の使い方が原因になってることがありました。
registerDefaultNetworkCallback() の実装を見ると、同時に 100 を超える NetworkCallback を register すると exception が投げられると書いてあります。
- /**
- * ...
- *
- * To avoid performance issues due to apps leaking callbacks, the system will limit the
- * number of outstanding requests to 100 per app (identified by their UID), ... If this limit is
- * exceeded, an exception will be thrown. ...
- */
- @RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
- public void registerDefaultNetworkCallback(@NonNull NetworkCallback networkCallback) {
- registerDefaultNetworkCallback(networkCallback, getDefaultHandler());
- }
それがどこか探したところ、coil の ImageLoader.kt にいる
- @JvmName("create")
- fun ImageLoader(context: Context): ImageLoader {
- return ImageLoader.Builder(context).build()
- }
coil では ImageLoader ごとに registerDefaultNetworkCallback() が呼ばれます。
ImageLoader.Builder の build() で RealImageLoader が作られ、NetworkObserver が作られ、 RealNetworkObserver() が作られます。
RealNetworkObserver の init で registerNetworkCallback() しています。
- private class RealNetworkObserver(
- private val connectivityManager: ConnectivityManager,
- private val listener: Listener
- ) : NetworkObserver {
- ...
- init {
- val request = NetworkRequest.Builder()
- .addCapability(NET_CAPABILITY_INTERNET)
- .build()
- connectivityManager.registerNetworkCallback(request, networkCallback)
- }
- ...
- }
- internal fun NetworkObserver(
- context: Context,
- listener: Listener,
- logger: Logger?
- ): NetworkObserver {
- val connectivityManager: ConnectivityManager? = context.getSystemService()
- ...
- return try {
- RealNetworkObserver(connectivityManager, listener)
- } catch (e: Exception) {
- logger?.log(TAG, RuntimeException("Failed to register network observer.", e))
- EmptyNetworkObserver()
- }
- }
こちらは共通の ImageLoader インスタンスが返されるので registerNetworkCallback() を呼び過ぎることにはなりません。
参考 : https://issuetracker.google.com/issues/231499040#comment3