瞭解如何使用 Cronet 程式庫在 Android 應用程式中執行網路作業。Cronet 是一種 Chromium 網路堆疊,可做為應用程式的程式庫,供您在應用程式中使用。如要進一步瞭解程式庫功能,請參閱「使用 Cronet 執行網路作業」。
在專案中設定程式庫
請按照下列步驟將依附元件新增至專案中的 Cronet 程式庫:
確認 Android Studio 在專案的
settings.gradle
檔案中加入 Google Maven 存放區的參照,如以下範例所示:Groovy
dependencyResolutionManagement { ... repositories { ... google() } }
Kotlin
dependencyResolutionManagement { ... repositories { ... google() } }
在應用程式模組
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 物件
如要建立網路要求,請呼叫 CronetEngine
的 newUrlRequestBuilder()
方法,傳遞到達網頁網址、回呼類別的執行個體和執行工具物件。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. … }