إرسال طلب بسيط

تعرَّف على كيفية استخدام مكتبة Cronet لتنفيذ عمليات على الشبكة في تطبيق Android. إنّ Cronet هو حزمة شبكة Chromium المتاحة كمكتبة يمكنك استخدامها في تطبيقاتك. لمزيد من المعلومات عن ميزات المكتبة، راجع تنفيذ عمليات الشبكة باستخدام Cronet.

إعداد المكتبة في مشروعك

اتبع هذه الخطوات لإضافة تبعية إلى مكتبة Cronet في مشروعك:

  1. تأكَّد من أنّ "استوديو Android" تضمّن مرجعًا إلى "مستودع Maven" من Google في ملف settings.gradle الخاص بمشروعك، على النحو الموضّح في المثال التالي:

    رائع

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

    Kotlin

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
    
  2. أدرِج مرجعًا لمكتبة برامج "خدمات Google Play" ضِمن قسم "dependencies" في ملف build.gradle الخاص بوحدة التطبيق على النحو الموضَّح في المثال التالي:

    رائع

    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 التي يتم إنشاؤها بعد إضافة هذه التبعية ستستخدم Cronet المحمَّل من "خدمات Google Play". عليك الاتصال CronetProviderInstaller.installProvider(Context) قبل إنشاء عناصر CronetEngine لمنع تنفيذ استثناءات غير متوقعة أثناء إنشاء CronetEngine بسبب أخطاء مثل الأجهزة التي تتطلب إصدارًا محدَّثًا من "خدمات Google Play".

في الحالات التي لا يمكن فيها تحميل Cronet من خدمات Google Play، يمكن استخدام واجهة برمجة تطبيقات Cronet أقل أداءً. لاستخدام عملية التنفيذ العكسي هذه، اعتمِد على 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، استخدِم إحدى الطرق الثابتة من الفئة Executors التي تُرجع كائن Executor. يوضّح المثال التالي كيفية إنشاء كائن Executor باستخدام الطريقة newSingleThreadExecutor():

Kotlin

val executor: Executor = Executors.newSingleThreadExecutor()

Java

Executor executor = Executors.newSingleThreadExecutor();

إنشاء كائن UrlRequest وإعداده

لإنشاء طلب الشبكة، استدعِ newUrlRequestBuilder() طريقة CronetEngine لتمرير عنوان 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. ويجب أن يدير تطبيقك الطلب خلال مراحل النشاط من خلال تحديد معاودة الاتصال لمعرفة المزيد من المعلومات عن دورة الحياة، يمكنك الاطّلاع على دورة حياة طلبات Chrome. يمكنك تحديد معاودة الاتصال عن طريق إنشاء فئة فرعية من 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.
  …
}