単純なリクエストの送信

Cronet ライブラリを使用して、Android アプリでネットワーク操作を実施する方法について説明します。Conet は、アプリで使用するライブラリとして利用可能な Chromium ネットワーク スタックです。ライブラリ機能の詳細については、Cronet を使用したネットワーク操作の実行をご覧ください。

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

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

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

    allprojects {
            repositories {
                ...
                google()
            }
        }
        
  2. Cronet の Google Play 開発者サービス クライアント ライブラリへの参照を、アプリ モジュールの build.gradle ファイルにある dependencies セクションに含めます。以下の例をご覧ください。

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

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

    Google Play 開発者サービスから Cronet を読み込めない場合、あまり効率のよくない Cronet API を実装することもできます。このフォールバックの実装は、org.chromium.net:cronet-fallback に依存しますが、new JavaCronetProvider(context).createBuilder() を呼び出します。

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

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

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

このライブラリには CronetEngine.Builder クラスが含まれています。これを使用して、CronetEngine のインスタンスを作成できます。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 to the read() 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.
            request?.read(ByteBuffer.allocateDirect(102400))
        }

        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 to the read() 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.
        request.read(ByteBuffer.allocateDirect(102400));
      }

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

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

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

Kotlin

    val executor: Executor = Executors.newSingleThreadExecutor()
    

Java

    Executor executor = Executors.newSingleThreadExecutor();
    

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

ネットワーク リクエストを作成するには、CronetEnginenewUrlRequestBuilder() メソッドを呼び出して、宛先 URL、コールバック クラスのインスタンス、executor オブジェクトを渡します。下記の例に示すように、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 をご覧ください。

ネットワーク タスクを開始するには、request の 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.
      …
    }