واجهة برمجة التطبيقات "مهام Google"

بدءًا من الإصدار 9.0.0 من "خدمات Google Play"، يمكنك استخدام واجهة برمجة تطبيقات Task عدد الطرق التي تعرض الدالة Task أو فئاتها الفرعية. Task هي واجهة برمجة تطبيقات يمثل طلبات طريقة غير متزامنة، على غرار PendingResult في العمليات السابقة من خدمات Google Play.

التعامل مع نتائج المهام

هناك طريقة شائعة تعرض Task هي FirebaseAuth.signInAnonymously(). وتعرض Task<AuthResult>، ما يعني أنّه سيتم عرض المهمة. كائن AuthResult عند نجاحه:

Task<AuthResult> task = FirebaseAuth.getInstance().signInAnonymously();

لتلقّي إشعار عند نجاح المهمة، يُرجى إرفاق OnSuccessListener:

task.addOnSuccessListener(new OnSuccessListener<AuthResult>() {
    @Override
    public void onSuccess(AuthResult authResult) {
        // Task completed successfully
        // ...
    }
});

لتلقّي إشعار عند تعذُّر المهمة، يُرجى إرفاق OnFailureListener:

task.addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        // Task failed with an exception
        // ...
    }
});

لمعالجة النجاح والفشل في المستمع نفسه، أرفِق OnCompleteListener:

task.addOnCompleteListener(new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        if (task.isSuccessful()) {
            // Task completed successfully
            AuthResult result = task.getResult();
        } else {
            // Task failed with an exception
            Exception exception = task.getException();
        }
    }
});

خيوط

يتم تشغيل أدوات معالجة الحدث المرفقة بسلسلة محادثات في سلسلة المحادثات الرئيسية للتطبيق (واجهة المستخدم) تلقائيًا. عند إرفاق مستمِع، يمكنك أيضًا تحديد Executor يُستخدم لجدولة المستمعين.

// Create a new ThreadPoolExecutor with 2 threads for each processor on the
// device and a 60 second keep-alive time.
int numCores = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor executor = new ThreadPoolExecutor(numCores * 2, numCores *2,
        60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());

task.addOnCompleteListener(executor, new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        // ...
    }
});

أدوات معالجة الأحداث على مستوى النشاط

إذا كنت تستمع إلى نتائج المهام في Activity، قد تريد إضافة المستمعين على مستوى النشاط للمهمة. تتم إزالة هؤلاء المستمعين أثناء طريقة onStop في نشاطك حتى لا يتم استدعاء المستمعين عندما لا يعود النشاط مرئيًا.

Activity activity = MainActivity.this;
task.addOnCompleteListener(activity, new OnCompleteListener<AuthResult>() {
    @Override
    public void onComplete(@NonNull Task<AuthResult> task) {
        // ...
    }
});

السلاسل

إذا كنت تستخدم واجهات برمجة تطبيقات متعددة تعرض السمة Task، يمكنك ربط سلسلة منها ببعضها. باستخدام المتابعة. يساعد ذلك في تجنُّب عمليات الاستدعاء والدمج المتداخلة التعامل مع الأخطاء لسلاسل المهام.

على سبيل المثال، تعرض الطريقة doSomething القيمة Task<String> ولكنها مطلوبة. علامة AuthResult، والتي سنحصل عليها بشكل غير متزامن من المهمة:

public Task<String> doSomething(AuthResult authResult) {
    // ...
}

باستخدام الطريقة Task.continueWithTask، يمكننا ربط هاتين المهمتين في سلسلة:

Task<AuthResult> signInTask = FirebaseAuth.getInstance().signInAnonymously();

signInTask.continueWithTask(new Continuation<AuthResult, Task<String>>() {
    @Override
    public Task<String> then(@NonNull Task<AuthResult> task) throws Exception {
        // Take the result from the first task and start the second one
        AuthResult result = task.getResult();
        return doSomething(result);
    }
}).addOnSuccessListener(new OnSuccessListener<String>() {
    @Override
    public void onSuccess(String s) {
        // Chain of tasks completed successfully, got result from last task.
        // ...
    }
}).addOnFailureListener(new OnFailureListener() {
    @Override
    public void onFailure(@NonNull Exception e) {
        // One of the tasks in the chain failed with an exception.
        // ...
    }
});

تؤدي إلى الحظر

إذا كان يتم تنفيذ البرنامج في سلسلة محادثات في الخلفية، يمكنك حظر مهمة للحصول على النتيجة بشكل متزامن وتجنب معاودة الاتصال:

try {
    // Block on a task and get the result synchronously. This is generally done
    // when executing a task inside a separately managed background thread. Doing this
    // on the main (UI) thread can cause your application to become unresponsive.
    AuthResult authResult = Tasks.await(task);
} catch (ExecutionException e) {
    // The Task failed, this is the same exception you'd get in a non-blocking
    // failure handler.
    // ...
} catch (InterruptedException e) {
    // An interrupt occurred while waiting for the task to complete.
    // ...
}

ويمكنك أيضًا تحديد مهلة عند حظر مهمة، بحيث لا لا تعلق:

try {
    // Block on the task for a maximum of 500 milliseconds, otherwise time out.
    AuthResult authResult = Tasks.await(task, 500, TimeUnit.MILLISECONDS);
} catch (ExecutionException e) {
    // ...
} catch (InterruptedException e) {
    // ...
} catch (TimeoutException e) {
    // Task timed out before it could complete.
    // ...
}

إمكانية التشغيل التفاعلي

يتوافق Task من الناحية النظرية مع العديد من أساليب Android الشائعة في إدارة ويمكن تحويل Task مباشرةً إلى رمز غير متزامن الأولية، بما فيها الكوروتينات ListenableFuture و Kotlin، وهي ينصح به AndroidX.

إليك مثال على استخدام السمة Task:

// ...
simpleTask.addOnCompleteListener(this) {
  completedTask -> textView.text = completedTask.result
}

كوروتين بلغة Kotlin

الاستخدام

أضف التبعية التالية إلى مشروعك واستخدم الكود أدناه لتحويل من Task.

Gradle (build.gradle على مستوى الوحدة، عادةً app/build.gradle)
// Source: https://github.com/Kotlin/kotlinx.coroutines/tree/master/integration/kotlinx-coroutines-play-services
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.7.3'
المقتطف
import kotlinx.coroutines.tasks.await
// ...
  textView.text = simpleTask.await()
}

مستقبل استماع جوفا

أضف التبعية التالية إلى مشروعك واستخدم الكود أدناه لتحويل من Task.

Gradle (build.gradle على مستوى الوحدة، عادةً app/build.gradle)
implementation "androidx.concurrent:concurrent-futures:1.2.0"
المقتطف
import com.google.common.util.concurrent.ListenableFuture
// ...
/** Convert Task to ListenableFuture. */
fun <T> taskToListenableFuture(task: Task<T>): ListenableFuture<T> {
  return CallbackToFutureAdapter.getFuture { completer ->
    task.addOnCompleteListener { completedTask ->
      if (completedTask.isCanceled) {
        completer.setCancelled()
      } else if (completedTask.isSuccessful) {
        completer.set(completedTask.result)
      } else {
        val e = completedTask.exception
        if (e != null) {
          completer.setException(e)
        } else {
          throw IllegalStateException()
        }
      }
    }
  }
}
// ...
this.listenableFuture = taskToListenableFuture(simpleTask)
this.listenableFuture?.addListener(
  Runnable {
    textView.text = listenableFuture?.get()
  },
  ContextCompat.getMainExecutor(this)
)

عناصر RxJava2 يمكن ملاحظتها

أضف التبعية التالية، بالإضافة إلى المكتبة النسبية غير المتزامنة إلى مشروعك واستخدام الرمز أدناه للتحويل من Task.

Gradle (build.gradle على مستوى الوحدة، عادةً app/build.gradle)
// Source: https://github.com/ashdavies/rx-tasks
implementation 'io.ashdavies.rx.rxtasks:rx-tasks:2.2.0'
المقتطف
import io.ashdavies.rx.rxtasks.toSingle
import java.util.concurrent.TimeUnit
// ...
simpleTask.toSingle(this).subscribe { result -> textView.text = result }

الخطوات التالية