単純なリクエストを送信する

Cronet ライブラリを使用して、Android アプリでネットワーク オペレーションを実行する方法について説明します。Cronet は、アプリで使用できるライブラリとして提供されている Chromium ネットワーク スタックです。ライブラリ機能の詳細については、Cronet を使用してネットワーク オペレーションを実行するをご覧ください。

プロジェクトでライブラリを設定する

プロジェクト内の Cronet ライブラリに依存関係を追加する手順は次のとおりです。

  1. 次の例に示すように、Android Studio でプロジェクトの settings.gradle ファイルに Google の Maven リポジトリへの参照が含まれていることを確認します。

    Groovy

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
    

    Kotlin

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
    
  2. 次の例に示すように、アプリ モジュールの build.gradle ファイルの dependencies セクションに、Cronet 用の Google Play 開発者サービス クライアント ライブラリへの参照を含めます。

    Groovy

    dependencies {
       implementation 'com.google.android.gms:play-services-cronet:18.0.1'
    }
    

    Kotlin

    dependencies {
       implementation("com.google.android.gms:play-services-cronet:18.0.1")
    }
    

この依存関係が追加されると作成された CronetEngine オブジェクトは、Google Play 開発者サービスから読み込まれた Cronet を使用します。CronetEngine オブジェクトを作成する前に CronetProviderInstaller.installProvider(Context) を呼び出すことで、Google Play 開発者サービスの更新バージョンを必要とするデバイスなどのエラーによって CronetEngine の作成時に予期しない例外がスローされることを防止できます。

Cronet を Google Play 開発者サービスから読み込めない場合は、Cronet の API のパフォーマンスの低い実装を使用できます。このフォールバック実装を使用するには、org.chromium.net:cronet-fallback に依存して new JavaCronetProvider(context).createBuilder() を呼び出します。

ネットワーク リクエストを作成する

このセクションでは、Cronet ライブラリを使用してネットワーク リクエストを作成し、送信する方法について説明します。ネットワーク リクエストを送信した後、アプリはネットワーク レスポンスを処理する必要があります。

CronetEngine のインスタンスを作成して設定する

ライブラリには、CronetEngine のインスタンスの作成に使用できる CronetEngine.Builder クラスが用意されています。次の例は、CronetEngine オブジェクトの作成方法を示しています。

Kotlin

val myBuilder = CronetEngine.Builder(context)
val cronetEngine: CronetEngine = myBuilder.build()

Java

CronetEngine.Builder myBuilder = new CronetEngine.Builder(context);
CronetEngine cronetEngine = myBuilder.build();

Builder クラスを使用して CronetEngine オブジェクトを構成できます。たとえば、キャッシュやデータ圧縮などのオプションを指定できます。詳細については、CronetEngine.Builder をご覧ください。

リクエスト コールバックの実装を提供する

コールバックの実装を提供するには、次の例に示すように、UrlRequest.Callback のサブクラスを作成し、必要な抽象メソッドを実装します。

Kotlin

private const val TAG = "MyUrlRequestCallback"

class MyUrlRequestCallback : UrlRequest.Callback() {
    override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
        Log.i(TAG, "onRedirectReceived method called.")
        // You should call the request.followRedirect() method to continue
        // processing the request.
        request?.followRedirect()
    }

    override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "onResponseStarted method called.")
        // You should call the request.read() method before the request can be
        // further processed. The following instruction provides a ByteBuffer object
        // with a capacity of 102400 bytes for the read() method. The same buffer
        // with data is passed to the onReadCompleted() method.
        request?.read(ByteBuffer.allocateDirect(102400))
    }

    override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
        Log.i(TAG, "onReadCompleted method called.")
        // You should keep reading the request until there's no more data.
        byteBuffer.clear()
        request?.read(byteBuffer)
    }

    override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
        Log.i(TAG, "onSucceeded method called.")
    }
}

Java

class MyUrlRequestCallback extends UrlRequest.Callback {
  private static final String TAG = "MyUrlRequestCallback";

  @Override
  public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
    Log.i(TAG, "onRedirectReceived method called.");
    // You should call the request.followRedirect() method to continue
    // processing the request.
    request.followRedirect();
  }

  @Override
  public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
    Log.i(TAG, "onResponseStarted method called.");
    // You should call the request.read() method before the request can be
    // further processed. The following instruction provides a ByteBuffer object
    // with a capacity of 102400 bytes for the read() method. The same buffer
    // with data is passed to the onReadCompleted() method.
    request.read(ByteBuffer.allocateDirect(102400));
  }

  @Override
  public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
    Log.i(TAG, "onReadCompleted method called.");
    // You should keep reading the request until there's no more data.
    byteBuffer.clear();
    request.read(byteBuffer);
  }

  @Override
  public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
    Log.i(TAG, "onSucceeded method called.");
  }
}

Executor オブジェクトを作成してネットワーク タスクを管理する

Executor クラスを使用すると、ネットワーク タスクを実行できます。Executor のインスタンスを取得するには、Executor オブジェクトを返す Executors クラスの静的メソッドのいずれかを使用します。次の例は、newSingleThreadExecutor() メソッドを使用して Executor オブジェクトを作成する方法を示しています。

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

UrlRequest オブジェクトを作成して設定する

ネットワーク リクエストを作成するには、CronetEnginenewUrlRequestBuilder() メソッドを呼び出して、宛先 URL、コールバック クラスのインスタンス、エグゼキュータ オブジェクトを渡します。次の例に示すように、newUrlRequestBuilder() メソッドは UrlRequest.Builder オブジェクトを返します。このオブジェクトを使用して、UrlRequest オブジェクトを作成できます。

Kotlin

val requestBuilder = cronetEngine.newUrlRequestBuilder(
        "https://www.example.com",
        MyUrlRequestCallback(),
        executor
)

val request: UrlRequest = requestBuilder.build()

Java

UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(
        "https://www.example.com", new MyUrlRequestCallback(), executor);

UrlRequest request = requestBuilder.build();

Builder クラスを使用して、UrlRequest のインスタンスを構成できます。たとえば、優先度や HTTP 動詞を指定できます。詳細については、UrlRequest.Builder をご覧ください。

ネットワーク タスクを開始するには、リクエストの start() メソッドを呼び出します。

Kotlin

request.start()

Java

request.start();

このセクションの手順に沿って、Cronet を使用してネットワーク リクエストを作成して送信できます。ただし、わかりやすくするために UrlRequest.Callback の実装例では、ログにメッセージが出力されるだけです。次のセクションでは、レスポンスからデータを抽出する、リクエストのエラーを検出するなど、より有用なシナリオをサポートするコールバックの実装方法について説明します。

ネットワーク レスポンスを処理する

start() メソッドを呼び出すと、Cronet リクエストのライフサイクルが開始されます。アプリはコールバックを指定して、ライフサイクル中にリクエストを管理する必要があります。ライフサイクルの詳細については、Cronet リクエストのライフサイクルをご覧ください。コールバックを指定するには、UrlRequest.Callback のサブクラスを作成して次のメソッドを実装します。

onRedirectReceived()

元のリクエストへのレスポンスとしてサーバーが HTTP リダイレクト コードを発行したときに呼び出されます。新しいリンク先にリダイレクトするには、followRedirect() メソッドを使用します。それ以外の場合は、cancel() メソッドを使用します。このメソッドの実装例を次に示します。

Kotlin

override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
  // Determine whether you want to follow the redirect.
  ...

  if (shouldFollow) {
      request?.followRedirect()
  } else {
      request?.cancel()
  }
}

Java

@Override
public void onRedirectReceived(UrlRequest request, UrlResponseInfo info, String newLocationUrl) {
  // Determine whether you want to follow the redirect.
  …

  if (shouldFollow) {
    request.followRedirect();
  } else {
    request.cancel();
  }
}
onResponseStarted()

ヘッダーの最終セットが受信されたときに呼び出されます。onResponseStarted() メソッドは、すべてのリダイレクトの後にのみ呼び出されます。次のコードは、このメソッドの実装例を示しています。

Kotlin

override fun onResponseStarted(request: UrlRequest?, info: UrlResponseInfo?) {
  val httpStatusCode = info?.httpStatusCode
  if (httpStatusCode == 200) {
    // The request was fulfilled. Start reading the response.
    request?.read(myBuffer)
  } else if (httpStatusCode == 503) {
    // The service is unavailable. You should still check if the request
    // contains some data.
    request?.read(myBuffer)
  }
  responseHeaders = info?.allHeaders
}

Java

@Override
public void onResponseStarted(UrlRequest request, UrlResponseInfo info) {
  int httpStatusCode = info.getHttpStatusCode();
  if (httpStatusCode == 200) {
    // The request was fulfilled. Start reading the response.
    request.read(myBuffer);
  } else if (httpStatusCode == 503) {
    // The service is unavailable. You should still check if the request
    // contains some data.
    request.read(myBuffer);
  }
  responseHeaders = info.getAllHeaders();
}
onReadCompleted()

レスポンス本文の一部が読み取られるたびに呼び出されます。次のコード例は、このメソッドを実装してレスポンスの本文を抽出する方法を示しています。

Kotlin

override fun onReadCompleted(request: UrlRequest?, info: UrlResponseInfo?, byteBuffer: ByteBuffer?) {
  // The response body is available, process byteBuffer.
  ...

  // Continue reading the response body by reusing the same buffer
  // until the response has been completed.
  byteBuffer?.clear()
  request?.read(myBuffer)
}

Java

@Override
public void onReadCompleted(UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) {
  // The response body is available, process byteBuffer.
  …

  // Continue reading the response body by reusing the same buffer
  // until the response has been completed.
  byteBuffer.clear();
  request.read(myBuffer);
}
onSucceeded()

ネットワーク リクエストが正常に完了したときに呼び出されます。次の例は、このメソッドの実装方法を示しています。

Kotlin

override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
    // The request has completed successfully.
}

Java

@Override
public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
  // The request has completed successfully.
}
onFailed()

start() メソッドが呼び出された後、なんらかの理由でリクエストが失敗した場合に呼び出されます。次の例は、このメソッドを実装してエラーに関する情報を取得する方法を示しています。

Kotlin

override fun onFailed(request: UrlRequest?, info: UrlResponseInfo?, error: CronetException?) {
    // The request has failed. If possible, handle the error.
    Log.e(TAG, "The request failed.", error)
}

Java

@Override
public void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
  // The request has failed. If possible, handle the error.
  Log.e(TAG, "The request failed.", error);
}
onCanceled()

cancel() メソッドを使用してリクエストがキャンセルされた場合に呼び出されます。呼び出されると、UrlRequest.Callback クラスの他のメソッドは呼び出されません。このメソッドを使用すると、リクエストの処理に割り当てられたリソースを解放できます。このメソッドの実装例を次に示します。

Kotlin

override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
    // Free resources allocated to process this request.
    ...
}

Java

@Override
public void onCanceled(UrlRequest request, UrlResponseInfo info) {
  // Free resources allocated to process this request.
  …
}