Mulai dari layanan Google Play versi 9.0.0, Anda dapat menggunakan Task
API dan
sejumlah metode yang menampilkan Task
atau subclass-nya. Task
adalah API yang merepresentasikan panggilan metode asinkron, mirip dengan PendingResult
dalam versi layanan Google Play sebelumnya.
Menangani hasil tugas
Metode umum yang menampilkan Task
adalah FirebaseAuth.signInAnonymously()
.
Metode ini akan menampilkan Task<AuthResult>
, yang berarti tugas akan menampilkan
objek AuthResult
saat berhasil:
Task<AuthResult> task = FirebaseAuth.getInstance().signInAnonymously();
Agar mendapatkan notifikasi saat tugas berhasil, lampirkan OnSuccessListener
:
task.addOnSuccessListener(new OnSuccessListener<AuthResult>() { @Override public void onSuccess(AuthResult authResult) { // Task completed successfully // ... } });
Agar mendapatkan notifikasi saat tugas gagal, lampirkan OnFailureListener
:
task.addOnFailureListener(new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } });
Untuk menangani keberhasilan dan kegagalan dalam pemroses yang sama, lampirkan 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(); } } });
Threading
Pemroses yang terpasang pada thread dijalankan pada thread utama aplikasi (UI) secara default. Saat melampirkan pemroses, Anda juga dapat menentukan Executor
yang
digunakan untuk menjadwalkan pemroses.
// 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) { // ... } });
Pemroses cakupan aktivitas
Jika memproses hasil tugas di Activity
, Anda mungkin ingin menambahkan
pemroses cakupan aktivitas ke tugas. Pemroses ini dihapus selama
metode onStop
Aktivitas Anda, sehingga pemroses tidak dipanggil
saat Aktivitas tidak lagi terlihat.
Activity activity = MainActivity.this; task.addOnCompleteListener(activity, new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { // ... } });
Perantaian
Jika menggunakan beberapa API yang menampilkan Task
, Anda dapat merangkainya menggunakan
kelanjutan. Hal ini membantu menghindari callback yang sangat bertingkat dan menggabungkan
penanganan error untuk rantai tugas.
Misalnya, metode doSomething
menampilkan Task<String>
, tetapi memerlukan
AuthResult
, yang akan kita dapatkan secara asinkron dari tugas:
public Task<String> doSomething(AuthResult authResult) { // ... }
Dengan metode Task.continueWithTask
, kita dapat merangkai dua tugas ini:
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. // ... } });
Pemblokiran
Jika program Anda sudah berjalan di thread latar belakang, Anda bisa memblokir sebuah tugas untuk mendapatkan hasil secara sinkron dan menghindari callback:
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. // ... }
Anda juga dapat menentukan waktu tunggu saat memblokir tugas sehingga aplikasi tidak hang:
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. // ... }
Interoperabilitas
Task
selaras secara konseptual dengan beberapa pendekatan Android populer untuk mengelola
kode asinkron, dan Task
dapat langsung dikonversi ke primitif
lainnya, termasuk coroutine ListenableFuture
dan Kotlin, yang
direkomendasikan oleh AndroidX.
Berikut adalah contoh penggunaan Task
:
// ... simpleTask.addOnCompleteListener(this) { completedTask -> textView.text = completedTask.result }
Coroutine Kotlin
Penggunaan
Tambahkan dependensi berikut ke project Anda dan gunakan kode di bawah ini untuk mengonversi
dari Task
.
Gradle (build.gradle
level modul, biasanya 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.4.1'
Cuplikan
import kotlinx.coroutines.tasks.await // ... textView.text = simpleTask.await() }
ListenableFuture Guava
Tambahkan dependensi berikut ke project Anda dan gunakan kode di bawah ini untuk mengonversi
dari Task
.
Gradle (build.gradle
level modul, biasanya app/build.gradle
)
implementation "androidx.concurrent:concurrent-futures:1.1.0"
Cuplikan
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 Observable
Tambahkan dependensi berikut, selain library asinkron relatif pilihan, ke project Anda dan gunakan kode di bawah ini untuk melakukan konversi dari Task
.
Gradle (build.gradle
level modul, biasanya app/build.gradle
)
// Source: https://github.com/ashdavies/rx-tasks implementation 'io.ashdavies.rx.rxtasks:rx-tasks:2.2.0'
Cuplikan
import io.ashdavies.rx.rxtasks.toSingle import java.util.concurrent.TimeUnit // ... simpleTask.toSingle(this).subscribe { result -> textView.text = result }