Gửi một yêu cầu đơn giản

Tìm hiểu cách sử dụng Thư viện Cronet để thực hiện các thao tác mạng trong Ứng dụng Android. Cronet là bộ phần cứng và phần mềm mạng Chromium được cung cấp dưới dạng thư viện để bạn sử dụng trong ứng dụng của mình. Để biết thêm thông tin về các tính năng của thư viện, hãy xem Thực hiện hoạt động mạng bằng cách sử dụng Cronet.

Thiết lập thư viện trong dự án

Hãy làm theo các bước sau để thêm phần phụ thuộc vào Thư viện Cronet trong dự án của bạn:

  1. Kiểm tra để đảm bảo rằng Android Studio đã tham chiếu đến kho lưu trữ Maven của Google trong tệp settings.gradle của dự án, như minh hoạ sau ví dụ:

    Groovy

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

    Kotlin

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
    
  2. Thêm mục tham chiếu đến Thư viện ứng dụng Dịch vụ Google Play cho Cronet trong phần dependencies trong tệp build.gradle của mô-đun ứng dụng, như như trong ví dụ sau:

    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")
    }
    

Các đối tượng CronetEngine sẽ được tạo sau khi phần phụ thuộc được thêm vào sẽ sử dụng Cronet được tải từ các dịch vụ Google Play. Gọi điện CronetProviderInstaller.installProvider(Context) trước khi tạo đối tượng CronetEngine để ngăn chặn các ngoại lệ không mong muốn được gửi trong quá trình tạo CronetEngine do các lỗi như thiết bị yêu cầu phiên bản cập nhật của Dịch vụ Google Play.

Trong trường hợp không thể tải Cronet từ các dịch vụ của Google Play, có thể sử dụng việc triển khai API của Cronet với hiệu suất kém hơn. Để sử dụng cách triển khai dự phòng này, phụ thuộc vào org.chromium.net:cronet-fallback và gọi new JavaCronetProvider(context).createBuilder().

Tạo yêu cầu kết nối mạng

Phần này cho biết cách tạo và gửi yêu cầu mạng bằng Cronet Thư viện. Sau khi gửi yêu cầu mạng, ứng dụng của bạn sẽ xử lý mạng .

Tạo và định cấu hình một bản sao của CronetEngine

Thư viện này cung cấp Lớp CronetEngine.Builder mà bạn có thể dùng để tạo một phiên bản CronetEngine. Ví dụ sau đây cho biết cách tạo đối tượng CronetEngine:

Kotlin

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

Java

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

Bạn có thể dùng lớp Builder để định cấu hình một CronetEngine. Ví dụ: bạn có thể cung cấp các tuỳ chọn như lưu vào bộ nhớ đệm và nén dữ liệu. Để biết thêm thông tin, hãy xem CronetEngine.Builder.

Cung cấp phương thức triển khai lệnh gọi lại yêu cầu

Để cung cấp phương thức triển khai lệnh gọi lại, hãy tạo một lớp con của UrlRequest.Callback và triển khai các phương thức trừu tượng bắt buộc, như trong ví dụ sau:

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.");
  }
}

Tạo đối tượng Thực thi để quản lý các tác vụ mạng

Bạn có thể sử dụng lớp Executor để thực thi mạng công việc. Để nhận thực thể của Executor, hãy sử dụng một trong các phương thức tĩnh của lớp Executors trả về đối tượng Executor. Ví dụ sau đây trình bày cách tạo Executor bằng cách sử dụng newSingleThreadExecutor() phương thức:

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

Tạo và định cấu hình đối tượng UrlRequest

Để tạo yêu cầu mạng, hãy gọi hàm newUrlRequestBuilder() của CronetEngine truyền giá trị URL đích, một bản sao của lớp gọi lại và đối tượng trình thực thi. Phương thức newUrlRequestBuilder() trả về một UrlRequest.Builder đối tượng mà bạn có thể dùng để tạo UrlRequest như trong ví dụ sau:

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();

Bạn có thể dùng lớp Builder để định cấu hình thực thể của UrlRequest. Cho ví dụ: bạn có thể chỉ định mức độ ưu tiên hoặc động từ HTTP. Để biết thêm thông tin, hãy xem UrlRequest.Builder.

Để bắt đầu tác vụ mạng, hãy gọi hàm Phương thức start() của yêu cầu:

Kotlin

request.start()

Java

request.start();

Bằng cách làm theo hướng dẫn trong phần này, bạn có thể tạo và gửi một mạng yêu cầu bằng Cronet. Tuy nhiên, để đơn giản, ví dụ việc triển khai Chỉ ảnh in UrlRequest.Callback một thông báo vào nhật ký. Phần sau đây trình bày cách cung cấp lệnh gọi lại để hỗ trợ nhiều trường hợp hữu ích hơn, chẳng hạn như trích xuất dữ liệu từ phản hồi và phát hiện lỗi trong yêu cầu.

Xử lý phản hồi mạng

Sau khi bạn gọi start() thì vòng đời yêu cầu Cronet sẽ được bắt đầu. Ứng dụng của bạn sẽ quản lý yêu cầu trong vòng đời bằng cách chỉ định một lệnh gọi lại. Để tìm hiểu thêm về chính sách vòng đời, hãy xem phần Yêu cầu của Chromium Lifecycle. Bạn có thể chỉ định một bằng cách tạo một lớp con của UrlRequest.Callback và triển khai các phương thức sau:

onRedirectReceived()

Được gọi khi máy chủ đưa ra mã chuyển hướng HTTP để phản hồi yêu cầu ban đầu. Để đi theo lệnh chuyển hướng đến đích đến mới, hãy sử dụng followRedirect() . Nếu không, hãy sử dụng cancel() . Ví dụ sau đây cho thấy cách triển khai phương thức này:

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()

Được gọi khi nhận được bộ tiêu đề cuối cùng. onResponseStarted() chỉ được gọi sau khi tuân theo tất cả các lệnh chuyển hướng. Mã sau đây cho thấy ví dụ về cách triển khai phương thức:

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()

Được gọi bất cứ khi nào một phần của nội dung phản hồi được đọc. Mã sau đây ví dụ cho biết cách triển khai phương thức và trích xuất nội dung phản hồi:

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()

Được gọi khi yêu cầu mạng hoàn tất thành công. Nội dung sau đây ví dụ cho thấy cách triển khai phương thức:

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()

Được gọi nếu yêu cầu không thành công vì bất kỳ lý do nào sau Đã gọi phương thức start(). Chiến lược phát hành đĩa đơn ví dụ sau cho biết cách triển khai phương thức và nhận thông tin về lỗi:

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()

Được gọi nếu yêu cầu bị huỷ bằng Phương thức cancel(). Sau khi được gọi, không có các phương pháp khác của Lớp UrlRequest.Callback là đã gọi. Bạn có thể sử dụng phương thức này để giải phóng tài nguyên được phân bổ nhằm xử lý một của bạn. Ví dụ sau đây cho thấy cách triển khai phương thức này:

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.
  …
}