ارسال درخواست ساده

با نحوه استفاده از «کتابخانه Cronet» برای انجام عملیات شبکه در برنامه Android خود آشنا شوید. Cronet پشته شبکه Chromium است که به‌عنوان کتابخانه‌ای برای استفاده در برنامه‌هایتان دردسترس قرار گرفته است. برای اطلاعات بیشتر درباره ویژگی‌های کتابخانه، انجام عملیات شبکه بااستفاده از Cronet را ببینید.

راه‌اندازی کتابخانه در پروژه

برای افزودن وابستگی به «کتابخانه Cronet» در پروژه‌تان، این مراحل را دنبال کنید:

  1. مطمئن شوید که «استودیو Android» ارجاعی به «مخزن Maven» متعلق به Google در فایل settings.gradle پروژه‌تان اضافه کرده باشد، همان‌طور که در مثال زیر نشان داده شده است:

    شیک

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

    کاتلین

    dependencyResolutionManagement {
       ...
       repositories {
           ...
           google()
       }
    }
  2. همان‌طور که در مثال زیر نشان داده شده است، ارجاعی به «کتابخانه مشتری خدمات Google Play» برای Cronet در بخش dependencies فایل build.gradle واحد برنامه‌تان اضافه کنید:

    شیک

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

    کاتلین

    dependencies {
       implementation("com.google.android.gms:play-services-cronet:18.0.1")
    }

CronetEngine اشیایی که پس‌از افزودن این وابستگی ایجاد می‌شوند، از Cronet بارشده از «خدمات Google Play» استفاده خواهند کرد. قبل‌از ایجاد اشیاء CronetEngine، CronetProviderInstaller.installProvider(Context) را فراخوانی کنید تا از ایجاد استثناهای غیرمنتظره درطول ایجاد CronetEngine به‌دلیل خطاهایی مثل نیاز دستگاه‌ها به نسخه به‌روزشده خدمات Google Play جلوگیری شود.

در مواردی که Cronet نمی‌تواند از خدمات Google Play بار شود، پیاده‌سازی با عملکرد ضعیف‌تری از Cronet API وجود دارد که می‌توان از آن استفاده کرد. برای استفاده از این پیاده‌سازی جایگزین، به org.chromium.net:cronet-fallback وابسته باشید و new JavaCronetProvider(context).createBuilder() را فراخوانی کنید.

ایجاد درخواست شبکه

این بخش نشان می‌دهد که چگونه بااستفاده از کتابخانه Cronet، درخواست شبکه ایجاد و ارسال کنید. پس‌از ارسال درخواست شبکه، برنامه‌تان باید پاسخ شبکه را پردازش کند.

ایجاد و پیکربندی نمونه‌ای از CronetEngine

کتابخانه کلاس CronetEngine.Builder را ارائه می‌دهد که می‌توانید از آن برای ایجاد نمونه‌ای از CronetEngine استفاده کنید. مثال زیر نحوه ایجاد شیء CronetEngine را نشان می‌دهد:

کاتلین

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

جاوا

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

می‌توانید از کلاس Builder برای پیکربندی شیء CronetEngine استفاده کنید، برای مثال می‌توانید گزینه‌هایی مثل ذخیره‌سازی در حافظه نهان و فشرده‌سازی داده‌ها را ارائه دهید. برای اطلاعات بیشتر، به CronetEngine.Builder مراجعه کنید.

پیاده‌سازی فراخوانی درخواست را ارائه دهید

برای ارائه پیاده‌سازی callback، یک زیرکلاس از UrlRequest.Callback ایجاد کنید و روش‌های انتزاعی موردنیاز را پیاده‌سازی کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

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

جاوا

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 را برمی‌گرداند استفاده کنید. مثال زیر نحوه ایجاد شیء Executor بااستفاده از روش newSingleThreadExecutor() را نشان می‌دهد:

کاتلین

val executor: Executor = Executors.newSingleThreadExecutor()

جاوا

Executor executor = Executors.newSingleThreadExecutor();

ایجاد و پیکربندی شیء UrlRequest

برای ایجاد درخواست شبکه، روش newUrlRequestBuilder() CronetEngine را با ارسال نشانی وب مقصد، نمونه‌ای از کلاس بازگشت تماس، و شیء اجراکننده فراخوانی کنید. روش newUrlRequestBuilder() شیء UrlRequest.Builder را برمی‌گرداند که می‌توانید از آن برای ساختن شیء UrlRequest استفاده کنید، همان‌طور که در مثال زیر نشان داده شده است:

کاتلین

val requestBuilder = cronetEngine.newUrlRequestBuilder(
        "https://www.example.com",
        MyUrlRequestCallback(),
        executor
)

val request: UrlRequest = requestBuilder.build()

جاوا

UrlRequest.Builder requestBuilder = cronetEngine.newUrlRequestBuilder(
        "https://www.example.com", new MyUrlRequestCallback(), executor);

UrlRequest request = requestBuilder.build();

می‌توانید از کلاس Builder برای پیکربندی نمونه UrlRequest استفاده کنید. برای مثال، می‌توانید اولویت یا فعل HTTP را مشخص کنید. برای اطلاعات بیشتر، به UrlRequest.Builder مراجعه کنید.

برای شروع کردن تکلیف شبکه، روش start() درخواست را فراخوانی کنید:

کاتلین

request.start()

جاوا

request.start();

با دنبال کردن دستورالعمل‌های این بخش، می‌توانید بااستفاده از Cronet درخواست شبکه ایجاد و ارسال کنید. بااین‌حال، برای سادگی، نمونه پیاده‌سازی UrlRequest.Callback فقط پیامی را در گزارش چاپ می‌کند. بخش زیر نشان می‌دهد چگونه پیاده‌سازی فراخوانی برگشتی را ارائه دهید که از سناریوهای مفیدتری پشتیبانی می‌کند، مانند استخراج داده‌ها از پاسخ و تشخیص خرابی در درخواست.

پردازش پاسخ شبکه

وقتی روش start() را فراخوانی می‌کنید، چرخه حیات درخواست Cronet آغاز می‌شود. برنامه شما باید درخواست را درطول چرخه حیات با مشخص کردن یک فراخوانی برگشتی مدیریت کند. برای کسب اطلاعات بیشتر درباره چرخه حیات، به چرخه حیات درخواست Cronet مراجعه کنید. می‌توانید با ایجاد زیرکلاس UrlRequest.Callback و پیاده‌سازی روش‌های زیر، فراخوانی برگشتی را مشخص کنید:

onRedirectReceived()

زمانی فراخوانی می‌شود که سرور کد تغییر مسیر HTTP را در پاسخ به درخواست اصلی صادر می‌کند. برای دنبال کردن تغییر مسیر به مقصد جدید، از روش followRedirect() استفاده کنید. درغیراین‌صورت، از روش cancel() استفاده کنید. مثال زیر نحوه پیاده‌سازی این روش را نشان می‌دهد:

کاتلین

override fun onRedirectReceived(request: UrlRequest?, info: UrlResponseInfo?, newLocationUrl: String?) {
  // Determine whether you want to follow the redirect.
  ...

  if (shouldFollow) {
      request?.followRedirect()
  } else {
      request?.cancel()
  }
}

جاوا

@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() فقط پس‌از دنبال شدن همه تغییرمسیرها فراخوانده می‌شود. کد زیر نمونه‌ای از پیاده‌سازی این روش را نشان می‌دهد:

کاتلین

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
}

جاوا

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

هرگاه بخشی از بدنه پاسخ خوانده شود، فراخوانی می‌شود. نمونه کد زیر نحوه پیاده‌سازی روش و استخراج بدنه پاسخ را نشان می‌دهد:

کاتلین

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

جاوا

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

وقتی درخواست شبکه با موفقیت تکمیل شود، فراخوانی می‌شود. مثال زیر نحوه پیاده‌سازی این روش را نشان می‌دهد:

کاتلین

override fun onSucceeded(request: UrlRequest?, info: UrlResponseInfo?) {
    // The request has completed successfully.
}

جاوا

@Override
public void onSucceeded(UrlRequest request, UrlResponseInfo info) {
  // The request has completed successfully.
}
onFailed()

اگر درخواست به‌هر دلیلی پس‌از فراخوانی روش start() ناموفق باشد، فراخوانی می‌شود. مثال زیر نشان می‌دهد که چگونه این روش را پیاده‌سازی کنید و اطلاعات مربوط به خطا را دریافت کنید:

کاتلین

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

جاوا

@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 فراخوانی نمی‌شود. می‌توانید از این روش برای آزاد کردن منابع اختصاص‌یافته برای پردازش درخواست استفاده کنید. مثال زیر نحوه پیاده‌سازی این روش را نشان می‌دهد:

کاتلین

override fun onCanceled(request: UrlRequest?, info: UrlResponseInfo?) {
    // Free resources allocated to process this request.
    ...
}

جاوا

@Override
public void onCanceled(UrlRequest request, UrlResponseInfo info) {
  // Free resources allocated to process this request.
  …
}