Android 開発で Glide はよく使われる画像ローダーライブラリの一つです。
この Glide にはネットワークエラーで画像の取得に失敗した場合でも、通信状況が復帰したタイミングで自動的に画像の再リクエストを行う機能があります。
この機能について深堀りしていきたいと思います。
※ 動作確認は Glide v4.12.0 で行っています。
画像再リクエストが行われるまでの流れ
Glide では DefaultConnectivityMonitor というクラスでネットワーク状況の監視が行われています。
ネットワーク状況が回復したタイミングで、このクラスは登録されたリスナーに通知します。
private final BroadcastReceiver connectivityReceiver =
new BroadcastReceiver() {
@Override
public void onReceive(@NonNull Context context, Intent intent) {
boolean wasConnected = isConnected;
isConnected = isConnected(context);
if (wasConnected != isConnected) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "connectivity changed, isConnected: " + isConnected);
}
listener.onConnectivityChanged(isConnected);
}
}
};
この通知は RequestManager.RequestManagerConnectivityListener#onConnectivityChanged メソッドで受け取り、このメソッド内で画像の再リクエストが行われます。
private class RequestManagerConnectivityListener
implements ConnectivityMonitor.ConnectivityListener {
@GuardedBy("RequestManager.this")
private final RequestTracker requestTracker;
RequestManagerConnectivityListener(@NonNull RequestTracker requestTracker) {
this.requestTracker = requestTracker;
}
@Override
public void onConnectivityChanged(boolean isConnected) {
if (isConnected) {
synchronized (RequestManager.this) {
requestTracker.restartRequests();
}
}
}
}
画像再リクエストが行われる条件
RequestManager のコンストラクタ にて ConnectivityMonitorFactory が ConnectivityMonitor のインスタンスを生成します。
RequestManager(
Glide glide,
Lifecycle lifecycle,
RequestManagerTreeNode treeNode,
RequestTracker requestTracker,
ConnectivityMonitorFactory factory,
Context context) {
this.glide = glide;
this.lifecycle = lifecycle;
this.treeNode = treeNode;
this.requestTracker = requestTracker;
this.context = context;
connectivityMonitor =
factory.build(
context.getApplicationContext(),
new RequestManagerConnectivityListener(requestTracker));
...
}
この ConnectivityMonitorFactory
は特に何も設定しなければ DefaultConnectivityMonitorFactory が使われます。
このクラスを見ると、android.permission.ACCESS_NETWORK_STATE
パーミッションが許可されている場合に DefaultConnectivityMonitor
を、そうでない場合は何もチェックを行わない NullConnectivityMonitor のインスタンスを生成するようになっています。
public ConnectivityMonitor build(
@NonNull Context context, @NonNull ConnectivityMonitor.ConnectivityListener listener) {
int permissionResult = ContextCompat.checkSelfPermission(context, NETWORK_PERMISSION);
boolean hasPermission = permissionResult == PackageManager.PERMISSION_GRANTED;
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(
TAG,
hasPermission
? "ACCESS_NETWORK_STATE permission granted, registering connectivity monitor"
: "ACCESS_NETWORK_STATE permission missing, cannot register connectivity monitor");
}
return hasPermission
? new DefaultConnectivityMonitor(context, listener)
: new NullConnectivityMonitor();
}
ですので AndroidManifest.xml
に android.permission.ACCESS_NETWORK_STATE
が設定されている場合などは、ネットワーク状況が回復したタイミングで画像の再リクエスト処理が行われることになります。
画像再リクエストを無効化する方法
この画像再リクエストの機能は、アプリによっては不要な場合もあり得るかと思います。
この機能を無効化するためには ConnectivityMonitorFactory
を継承したクラスを作成し、何もしない ConnectivityMonitor
を返すようにします。
そのためには AppGlideModule
を継承したクラスで以下のように設定することで可能になります。
@GlideModule
class GlideModule : AppGlideModule() {
override fun applyOptions(context: Context, builder: GlideBuilder) {
...
builder.setConnectivityMonitorFactory { _, _ -> NullConnectivityMonitor() }
}
private class NullConnectivityMonitor : ConnectivityMonitor {
override fun onStart() {
}
override fun onStop() {
}
override fun onDestroy() {
}
}
}