傳送簡單的要求

瞭解如何使用 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),以免在建立 CronetEngine 期間因裝置需要更新 Google Play 服務版本等錯誤而擲回非預期的例外狀況。

如果無法從 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 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 的執行個體,請使用 Executors 類別當中傳回 Executor 物件的靜態方法。以下範例說明如何使用 newSingleThreadExecutor() 方法建立 Executor 物件:

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

建立及設定 UrlRequest 物件

如要建立網路要求,請呼叫 CronetEnginenewUrlRequestBuilder() 方法,傳遞到達網頁網址、回呼類別的執行個體和執行工具物件。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.
  …
}