Ada dua cara
untuk melakukan pemrosesan latar belakang di Android: menggunakan kelas
AsyncTask, atau menggunakan kerangka kerja Loader, yang menyertakan kelas AsyncTaskLoader
yang menggunakan AsyncTask. Di sebagian besar situasi, Anda akan memilih
kerangka kerja Loader, namun penting untuk mengetahui cara kerja AsyncTask, sehingga
Anda bisa membuat pilihan yang bagus.
Dalam bab ini
Anda akan mempelajari alasan pentingnya memproses beberapa tugas di latar
belakang, di luar thread UI. Anda akan mempelajari cara menggunakan AsyncTask, bila
tidak menggunakan AsyncTask, dan dasar-dasar penggunaan loader.
A.
Thread
UI
Bila aplikasi
Android dimulai, aplikasi membuat thread utama, yang sering disebut thread UI.
Thread UI mengirimkan kejadian ke widget antarmuka pengguna (UI) yang sesuai,
dan ini merupakan tempat aplikasi Anda berinteraksi dengan komponen dari
toolkit UI Android (komponen dari paket android.widget dan android.view). Model
thread Android memiliki dua aturan :
1.
Jangan memblokir Thread UI.
Thread UI perlu memberikan perhatiannya
untuk menggambar UI dan menjaga aplikasi tetap responsif terhadap masukan
pengguna. Jika semuanya terjadi di thread UI, operasi panjang seperti akses
jaringan atau kueri database bisa memblokir seluruh UI. Dari perspektif
pengguna, aplikasi tersebut akan mogok. Lebih buruk lagi, jika thread UI
diblokir selama lebih dari beberapa detik (saat ini sekitar 5 detik) pengguna
akan ditampilkan dialog "application not responding" (ANR). Pengguna
bisa memutuskan untuk keluar dari aplikasi dan mencopot pemasangannya.
Untuk
memastikan aplikasi Anda tidak memblokir thread UI :
·
Selesaikan semua pekerjaan dalam waktu kurang
dari 16 md untuk setiap layar UI.
· Jangan menjalankan tugas asinkron dan tugas lain yang berjalan lama pada thread UI. Sebagai gantinya, implementasikan tugas pada thread latar belakang menggunakan AsyncTask (untuk tugas singkat atau yang bisa disela) atau AsyncTaskLoader (untuk tugas berprioritas tinggi, atau tugas yang perlu melaporkan kembali ke pengguna atau UI).
2.
Lakukan pekerjaan UI hanya pada thread UI.
Jangan menggunakan thread latar belakang
untuk memanipulasi UI Anda, karena toolkit UI Android bukan thread-safe.
B.
AsyncTask
Gunakan kelas AsyncTask untuk mengimplementasikan tugas asinkron yang berjalan lama di thread pekerja. (Thread pekerja adalah thread yang bukan thread utama atau thread UI.) AsyncTask memungkinkan Anda menjalankan operasi latar belakang dan mempublikasikan hasil di thread UI tanpa memanipulasi thread atau penangan.
Bila AsyncTask
dieksekusi, maka akan melalui empat langkah :
1.
onPreExecute( ) dipanggil di thread UI sebelum
tugas dieksekusi. Langkah ini biasanya digunakan untuk mempersiapkan tugas,
misalnya dengan menampilkan bilah kemajuan di UI.
2.
doInBackground( Params. . . ) dipanggil pada
thread latar belakang segera setelah onPreExecute( ) selesai. Langkah ini
menjalankan komputasi latar belakang, mengembalikan hasil, dan meneruskan
hasilnya ke onPostExecute( ) . Metode doInBackground( ) juga bisa memanggil
publishProgress( Progress. . . ) untuk mempublikasikan satu atau beberapa unit
kemajuan.
3.
onProgressUpdate( Progress. . . ) berjalan di
thread UI setelah publishProgress (Progress. . . ) dipanggil. Gunakan
onProgressUpdate( ) untuk melaporkan suatu bentuk kemajuan ke thread UI sewaktu
komputasi latar belakang dieksekusi. Misalnya, Anda bisa menggunakannya untuk
meneruskan data guna menganimasikan bilah kemajuan atau menampilkan log di
bidang teks.
4.
onPostExecute( Result) berjalan di thread UI
setelah komputasi latar belakang selesai.
C.
Penggunaan
AsyncTask
Untuk menggunakan kelas AsyncTask , definisikan subkelas AsyncTask yang menggantikan metode doInBackground( Params. . . ) (dan biasanya juga metode onPostExecute( Result) ). Bagian ini menjelaskan parameter dan penggunaan AsyncTask , kemudian menampilkan contoh lengkap.
D.
Parameter
AsyncTask
Di
subkelas AsyncTask , sediakan tipe data untuk tiga jenis parameter.
·
"Params" menetapkan tipe parameter
yang diteruskan ke doInBackground( ) sebagai larik.
·
"Progress" menetapkan tipe parameter
yang diteruskan ke publishProgress( ) di thread latar belakang. Parameter ini
selanjutnya diteruskan ke metode onProgressUpdate( ) di thread utama.
·
"Result" menetapkan tipe parameter
yang dikembalikan doInBackground( ) . Parameter ini secara otomatis diteruskan
ke onPostExecute( ) di thread utama.
Tetapkan tipe data untuk setiap tipe parameter ini, atau gunakan Void
jika tipe parameter tidak akan digunakan. Misalnya :
public class MyAsyncTask extends AsyncTask <String, Void, Bitmap>{}
Dalam deklarasi kelas ini :
·
Tipe parameter "Params" adalah String
, yang berarti bahwa MyAsyncTask memerlukan satu atau beberapa string sebagai
parameter di doInBackground( ), misalnya untuk digunakan di kueri.
·
Tipe parameter "Progress" adalah Void,
yang berarti bahwa MyAsyncTask tidak akan menggunakan metode publishProgress()
atau onProgressUpdate().
·
Tipe parameter "Result" adalah Bitmap.
MyAsyncTask mengembalikan Bitmap di doInbackground( ), yang diteruskan ke dalam
onPostExecute( ) .
E. Contoh AsyncTask
Contoh di atas
melewati tiga dari empat langkah-langkah AsyncTask dasar :
1.
doInBackground( ) mengunduh materi, tugas yang
berjalan lama. Langkah ini menghitung persentase file yang diunduh dari indeks
loop for dan meneruskannya ke publishProgress(). Pemeriksaan untuk isCancelled(
) di dalam loop for memastikan bahwa tugas telah dibatalkan, sistem tidak
menunggu hingga loop selesai.
2.
onProgressUpdate() memperbarui kemajuan
persentase. Ini dipanggil setiap kali metode publishProgress() dipanggil di
dalam doInBackground( ) , yang memperbarui kemajuan persentase.
3.
doInBackground( ) menghitung jumlah total byte
yang diunduh dan mengembalikannya. onPostExecute( ) menerima hasil yang
dikembalikan dan meneruskannya ke dalam onPostExecute( ) , yang ditampilkan di
dialog.
Tipe parameter yang digunakan dalam contoh ini adalah:
·
URL untuk tipe parameter "Params".
Tipe URL berarti Anda bisa meneruskan sejumlah URL ke dalam panggilan, dan URL
secara otomatis diteruskan ke dalam metode doInBackground( ) sebagai larik.
·
Integer untuk tipe parameter
"Progress".
·
Long untuk tipe parameter "Result".
F.
Mengeksekusi
AsyncTask
Setelah
Anda mendefinisikan subkelas AsyncTask , buat instance-nya di thread UI. Kemudian
panggil execute( ) di instance, dengan meneruskan sejumlah parameter. (Parameter
tersebut sesuai dengan tipe parameter "Params" yang dibahas di atas).
Misalnya,
untuk mengeksekusi tugas DownloadFilesTask yang didefinisikan di atas, gunakan
baris kode berikut :
new
DownloadFilesTask( ) . execute( url1, url2, url3) ;
G.
Membatalkan
AsyncTask
Anda
bisa membatalkan tugas kapan saja, dari thread apa pun, dengan memanggil metode
cancel( ) .
·
Metode cancel( ) akan mengembalikan false jika
tugas tidak bisa dibatalkan, biasanya karena sudah diselesaikan secara normal.
Jika tidak, cancel( ) akan mengembalikan true.
·
Untuk mengetahui apakah tugas sudah dibatalkan,
periksa nilai yang dikembalikan isCancelled( ) secara berkala dari
doInBackground( Obj ect[] ) , misalnya dari dalam loop seperti yang ditampilkan
dalam contoh di atas. Metode isCancelled( ) akan mengembalikan true jika tugas
dibatalkan sebelum diselesaikan secara normal.
·
Setelah tugas AsyncTask dibatalkan,
onPostExecute( ) tidak akan digunakan setelah doInBackground( ) dikembalikan.
Sebagai gantinya, onCancelled( Obj ect) akan dipanggil. Implementasi default
onCancelled( Obj ect) cukup memanggil onCancelled( ) dan mengabaikan hasil.
·
Secara default, tugas yang sedang diproses boleh
diselesaikan. Untuk memperbolehkan cancel( ) menyela thread yang sedang
mengeksekusi tugas, teruskan true untuk nilai mayInterruptIfRunning
H.
Keterbatasan
AsyncTask
AsyncTask
tidak praktis untuk beberapa kasus penggunaan :
1.
Perubahan pada konfigurasi perangkat menyebabkan
masalah. Bila konfigurasi perangkat berubah sewaktu AsyncTask berjalan,
misalnya jika pengguna mengubah orientasi layar, aktivitas yang membuat
AsyncTask akan dimusnahkan dan dibuat ulang. Metode AsyncTask tidak dapat
mengakses aktivitas yang baru saja dibuat dan hasil AsyncTask tidak akan
dipublikasikan.
2.
Objek AsyncTask lama tetap ada, dan aplikasi
Anda bisa kehabisan memori atau mogok. Jika aktivitas yang membuat AsyncTask
dimusnahkan, AsyncTask tidak akan dimusnahkan bersamanya. Misalnya, jika
pengguna keluar dari aplikasi setelah AsyncTask dimulai, AsyncTask akan terus
menggunakan sumber daya kecuali jika Anda memanggil cancel( ) .
Bila
menggunakan AsyncTask :
·
Tugas singkat atau yang bisa disela.
·
Tugas yang tidak perlu untuk melaporkan kembali
ke UI atau pengguna.
·
Tugas dengan prioritas rendah yang bisa
ditinggalkan sebelum selesai.
Untuk semua situasi lainnya, gunakan AsyncTaskLoader , adalah bagian
dari kerangka kerja Loader yang akan dijelaskan berikutnya.
I.
Loader
Tugas
latar belakang biasanya digunakan untuk memuat data seperti laporan prakiraan cuaca
atau ulasan film. Pemuatan data bisa jadi banyak menggunakan memori, dan Anda ingin
data tersedia sekalipun jika konfigurasi perangkat berubah. Untuk situasi ini,
gunakan loader, yang berupa rangkaian kelas yang memfasilitasi pemuatan data ke
dalam aktivitas.
Loader
menggunakan kelas LoaderManager untuk mengelola satu atau beberapa loader.
LoaderManager menyertakan serangkaian callback bila loader telah dibuat, bila pemuatan
datanya selesai, dan bila disetel ulang. Memulai loader Gunakan kelas
LoaderManager untuk mengelola satu atau beberapa instance Loader dalam
aktivitas atau fragmen.
Gunakan
initLoader( ) untuk melakukan inisialisasi dan mengaktifkannya. Biasanya, Anda
melakukan ini dalam metode onCreate( ) aktivitas. Misalnya :
// Prepare the loader. Either reconnect
with an existing one,
// or start a new one.getLoaderManager( ) .
initLoader( 0, null, this) ;
Jika
Anda menggunakan Pustaka Dukungan, buat panggilan ini menggunakan getSupportLoaderManager(
) sebagai ganti getLoaderManager( ) . Misalnya :
getSupportLoaderManager(
) . initLoader( 0, null, this) ;
Metode
initLoader( ) memerlukan tiga parameter:
1.
ID unik yang mengidentifikasi loader. ID ini
bisa berupa apa saja yang Anda inginkan.
2.
Argumen opsional yang disediakan ke loader saat
pembuatan, dalam bentuk Bundle. Jika loader sudah ada, parameter ini akan
diabaikan.
3.
Implementasi LoaderCallbacks , yang dipanggil
oleh LoaderManager untuk melaporkan kejadian loader. Dalam contoh ini, kelas
lokal mengimplementasikan antarmuka LoaderManager. LoaderCallbacks , sehingga
meneruskan referensi ke dirinya sendiri, this .
Panggilan initLoader( ) memiliki dua kemungkinan hasil
:
·
Jika loader yang ditetapkan melalui ID sudah
ada, maka loader yang dibuat terakhir menggunakan ID itu akan digunakan
kembali.
·
Jika loader yang ditetapkan melalui ID tidak
ada, initLoader( ) akan memicu metode onCreateLoader) .Di sinilah Anda
mengimplementasikan kode untuk membuat instance dan mengembalikan loader baru.
Catatan:Bila
initLoader( ) membuat loader atau menggunakan kembali loader yang ada, Implementasi
LoaderCallbacks yang diberikan akan dikaitkan dengan loader dan dipanggil bila keadaan
loader berubah. Jika loader yang diminta sudah ada dan sudah menghasilkan data,
maka sistem segera memanggil onLoadFinished( ) (selama initLoader( ) ), jadi
bersiaplah jika hal ini terjadi.
Masukkan
panggilan ke initLoader( ) di onCreate( ) sehingga aktivitas bisa dihubungkan kembali
ke loader yang sama bila konfigurasi berubah. Dengan cara itu, loader tidak kehilangan
data yang sudah dimuatnya.
J.
Memulai
ulang loader
Bila
initLoader( ) menggunakan kembali loader yang ada, maka data yang telah dimuat loader
tidak akan diganti, namun kadang-kadang Anda perlu menggantinya. Misalnya, bila
Anda menggunakan kueri pengguna untuk melakukan penelusuran dan pengguna memasukkan
kueri baru, Anda perlu memuat ulang data dengan menggunakan istilah penelusuran
baru. Dalam situasi ini, gunakan metode restartLoader( ) dan teruskan ID loader
yang ingin dimulai ulang. Hal ini akan memaksa muatan data lain dengan data masukan
baru.
K.
Tentang
metode restartLoader( ) :
restartLoader(
) menggunakan argumen yang sama dengan initLoader( ) . restartLoader( ) akan
memicu metode onCreateLoader( ) , seperti yang dilakukan initLoader( ) saat membuat
loader baru. Jika sudah ada loader dengan ID yang diberikan, restartLoader( ) akan
memulai ulang loader yang diidentifikasi dan mengganti datanya. Jika tidak ada
loader dengan ID yang diberikan, restartLoader( ) akan memulai loader baru.
L.
Callback
LoaderManager
Objek
LoaderManager secara otomatis memanggil onStartLoading( ) saat membuat loader.
Setelah itu, LoaderManager akan mengelola keadaan loader berdasarkan pada keadaan
aktivitas dan data, misalnya dengan memanggil onLoadFinished( ) bila data telah
dimuat. Untuk berinteraksi dengan loader, gunakan salah satu callback
LoaderManager di aktivitas yang memerlukan data: Panggil onCreateLoader( ) agar
bisa membuat instance dan mengembalikan loader baru untuk ID yang diberikan.
Panggil
onLoadFinished( ) bila loader yang dibuat sebelumnya selesai memuat. Di sinilah
Anda biasanya ingin memindahkan data ke dalam tampilan aktivitas.
Panggil
onLoaderReset( ) bila loader yang dibuat sebelumnya sedang disetel ulang, sehingga
datanya tidak tersedia.
Di
sinilah aplikasi harus membuang semua referensi apa pun yang dimilikinya ke
data loader. Subkelas Loader bertanggung jawab atas pemuatan data sebenarnya.
Subkelas Loader yang Anda gunakan bergantung pada tipe data yang dimuat, namun
salah satu yang paling mudah adalah AsyncTaskLoader, yang akan dijelaskan
berikutnya. AsyncTaskLoader menggunakan AsyncTask untuk menjalankan tugas pada
thread pekerja.
M.
AsyncTaskLoader
AsyncTaskLoader
adalah loader yang setara dengan AsyncTask. AsyncTaskLoader menyediakan metode,
loadInBackground( ), yang dijalankan di thread terpisah. Hasil
loadInBackground( ) secara otomatis dikirimkan ke thread UI, melalui
onLoadFinished( ) LoaderManager callback.
N.
Penggunaan
AsyncTaskLoader
Untuk
mendefinisikan subkelas AsyncTaskLoader , buat kelas yang memperluas AsyncTaskLoader<D>
, dalam hal ini Dadalah tipe data yang sedang Anda muat. Misalnya, AsyncTaskLoader
ini akan memuat daftar string: public static class StringListLoader extends AsyncTaskLoader<List<String>>
{}
Berikutnya,
implementasikan konstruktor yang cocok dengan implementasi super kelas: Konstruktor
menggunakan konteks aplikasi sebagai argumen dan meneruskannya ke panggilan
untuk super() . Jika loader Anda memerlukan informasi tambahan untuk melakukan
pemuatan, konstruktor bisa mengambil argumen tambahan. Dalam contoh yang
ditampilkan di bawah ini, konstruktor menggunakan sebuah istilah kueri.
public
StringListLoader(Context context, String queryString) {
super(context);
mQueryString
= queryString;
}
Untuk
melakukan pemuatan, gunakan metode penggantian loadInBackground( ) , akibat metode
doInBackground( ) dari AsyncTask . Misalnya :
@Override
public
List<String> loadInBackground() {
List<String>
data = new ArrayList<String>;
//TODO:
Load the data from the network or from a database
return
data;
}
O.
Mengimplementasikan
callback
Gunakan
konstruktor di callback onCreateLoader() LoaderManager , yang merupakantempat
membuat loader baru. Misalnya, callback onCreateLoader() ini menggunakan
konstruktor StringListLoader yang didefinisikan di atas :
@Override
public
Loader<List<String>> onCreateLoader(int id, Bundle args) {
return
new StringListLoader(this, args. getString("queryString"));
}
Hasil
loadInBackground() secara otomatis diteruskan ke dalam callback onLoadFinished(
) , di sinilah Anda bisa menampilkan hasil di UI. Misalnya :
public
void onLoadFinished(Loader<List<String>> loader,
List<String>
data) {
mAdapter.
setData(data);
}
Callback
onLoaderReset( ) hanya dipanggil bila loader akan dimusnahkan, sehingga seringkali
Anda bisa mengosongkan onLoaderReset( ) , karena Anda tidak akan mencoba mengakses
data setelah loader ini dimusnahkan.
Bila
Anda menggunakan AsyncTaskLoader, data Anda akan bertahan bila ada perubahan konfigurasi
perangkat. Jika aktivitas Anda dmusnahkan secara permanen, loader ini akan dimusnahkan
bersamanya, tanpa tugas yang menanti danmengonsumsi sumber daya sistem.
Loader
juga memiliki manfaat lain, misalnya loader bisa memantau perubahan sumber data
dan memuat ulang data jika terjadi perubahan. Anda akan mengetahui selengkapnya
tentang loader tertentu di pelajaran berikutnya.
Contoh
program AsyncTaskDownload sebagai berikut :
1. Pertama
jalankan aplikasi IDE Android Studio, caranya :
a.
Pilih Start → Android Studio
b.
Pilih → Start a new Android Studio Project
c.
Pilih → Empty Activity → Next
Configure Your Project
·
Name : Modul9AsyncTaskDownload
·
Package
Name : Diubah menjadi nama blog
masing – masing, disini saya akan menggunakan url blog saya gustidjafiralasdialbar.blogspot.com
lalu diikuti nama project modul9asynctaskdownload
·Save
Location :
D:\2021\semester6\ti1\14518489_GustiDjafiralAsdiAlbar\Modul9AsyncTaskDownload
·
Language : Java
·
Minimum
SDK : API 16: Android 4.1 (Jelly
Bean)
2.
Maka
akan Tampil IDE Android Studio, setelah itu Buka dan ubah script activity_main.xml menjadi seperti
gambar di bawah ini
maka akan terlihat seperti ini :
3.
Setelah
itu Buka dan ubah script MainActivity.java
menjadi seperti gambar di bawah ini
4.
Buat
sebuah file xml baru dengan Nama network_security_config.xml
di dalam folder /res/xml dan ketikan kode program berikut seperti gambar di
bawah ini
File ini digunakan agar aplikasi
bisa mengakses url yang tanpa SSL (url https), dan struktur nya sendiri akan
menjadi seperti gambar di bawah ini
5.
Sesuaikan
script AndroidManifest.xml seperti
di bawah ini untuk mendaftarkan komponen Intent
Filter dan mendaftarkan permission
akses internet & write external storage yang kita butuhkan
6.
Kemudian
buka Vysor dan jalankan scriptnya, maka akan muncul tampilan seperti ini
Aplikasi akan meminta akses ke
media penyimpanan anda, pilih izinkan selanjutnya
tekan tombol download Kembali
maka progress download akan terlihat di layer.
Selanjutnya coba cek di folder
.../download/ menggunakan file manager. Dan coba buka
file hasil download tersebut
Komentar
Posting Komentar