1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Android]Glideのネットワークエラー後の画像再リクエスト機能について

Last updated at Posted at 2021-03-08

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 のコンストラクタ にて ConnectivityMonitorFactoryConnectivityMonitor のインスタンスを生成します。

  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.xmlandroid.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() {
        }
    }
}
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?