بدءًا من الإصدار 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 }