KONSEP DAN TUTORIAL PENGGUNAAN ASYNCTASK DAN ASYNCTASLOADER PADA ANDROID STUDIO

 Assalamualaikum

Hallo sahabat blogger ! Ketemu lagi di blog NR Informatika, disini saya banyak menulis artikel tutorial-tutorial android, java netbean, dan web(html dan bootsrap). Nah pada kesempatan yang bagus ini, saya mau membagikan ilmu atau pengetahuan tentang AsyncTask dan AsyncTaskLoader pada Android Studio.

    Ada dua cara untuk melakukan pemrosesan latar belakang di Android : menggunakan kelas AsyncTask, atau menggunakan kerja Loader yang menyertakan kelas AsyncTaskLoader yang menggunakan AsyncTask. Disebagian besar situasi, anda akan memilih kerangka kerja Loader, namun penting untuk mengetahui cara kerja AsyncTask, sehingga anda bisa membuat pilihan yang bagus. 

    Saat anda menggunakan AsyncTask untuk melakukan operasi dilatar belakang, utas latar belakang itu tidak dapat memperbaharui UI jika perubahan konfigurasi terjadi saat tugas latar belakang berjalan. Untuk mengatasi situasi ini gunakan AsyncTaskLoader kelas. AsyncTaskLoader memuat data di latar belakang dan mengaitkan kembali tugas-tugas latar belakang dengan Activity, bahkan setelah perubahan konfigurasi. Dengan AsyncTaskLoader jika anda memutar perangkat saat sedang berjalan, hasilnya masih ditampilkan dengan benar di Activity.

    Mengapa menggunakan AsyncTask jika AsyncTaskLoader jauh lebih bermanfaat? Jawabannya tergantung pada situasi. Jika latar belakang cenderung selesai sebelum perubahan konfigurasi terjadi dan itu tidak penting untuk tugas memperbaharui UI, AsyncTask mungkin sudah cukup.

Dalam artikel ini akan mempelajari alasan pentingnya memproses beberapa tugas di latar belakang, di luar tread UI. Di artikel ini akan mempelajari cara menggunakan AsynTask, bila tidak menggunakan AsyncTask, dan dasar-dasar penggunaan loader.


A. Thread UI
    Thread adalah sekumpulan perintah yang dapat di eksekusi secara bersamaan dengan thread lainnya. Hal ini dicapai dengan menggunakan mekanisme Time Slice (ketika satu CPU melakukan perpindahan antara satu thread ke thread lainnya) atau mekanisme multiprocess (ketika thread-thread tersebut dilaksanakan oleh CPU yang berbeda dalam satu sistem).
    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 berinteraksi dengan komponen dari toolkit UI Android (Komponen dari paket android.widget dan android.view).

Model Thread Android memiliki dua aturan, yaitu:
1. Jangan memblokir thread UI

    Thread UI perlu memusatkan perhatiannya untuk menyusun UI dan menjaga aplikasi untuk tetap responsif terhadap masukan pengguna. Jika semua terjadi di Thread UI, operasi panjang seperti akses jaringan bisa memblokir seluruh tampilan Aplikasi. Hal ini akan mengakibatkan aplikasi akan berhenti atau Application Not Responding kemungkinan pengguna bisa keluar aplikasi dan Unistall aplikasi.
Cara untuk memastikan aplikasi anda tidak memblokir thread UI, yaitu:
→ Selesaikan semua pekerjaan dalam waktu kurang dari 16md untuk setiap layar UI.
→ Jangan jalankan 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 AsyncTaskLoader(untuk tugas berprioritas tinggi).

2. Lakukan pekerjaan UI hanya pada thread UI

    Jangan menggunakan thread latar belakang untuk memanipulasi UI, 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 UI). AsyncTask memungkinkan anda menjalankan operasi latar belakang dan mempublikasikan hasil di Thread UI tanpa memanipulasi thread.
Bila AsyncTask dieksekusi, maka akan melalui empat langkah berikut:
1. onPreExecute(),dipanggil di Thread UI sebelum tugas dieksekusi. Langkah ini biasanya digunakan untuk mempersiapkan tugas, misal dengan menampilkan bilah kemajuan di UI.
2. doInBackground(Paerams....), dipanggil pada Background Thread setelah onPreExecute() selesesai dijalankan. Langkah ini menjalankan komputasi dilatar belakang, mengembalikan hasil dan meneruskan hasilnya ke onPreExecute(). Metode ini juga bisa memanggil publishProgress(Progress...) untuk mempublikasikan satu atau beberapa unit kemajuan.
3. onProgressUpdate(Progress...) berjalan di Thread UI setelah publishProgress(Progress...) dipanggil. Gunakan ini untuk melaporkan suatu bentuk kemajuan ke Thread UI sewaktu komputeasi latar belakang diekskusi. Misal, untuk menerukan data guna menganimasikan bilah kemajuan.
4. onPostExecute(Result), berjalan di Thread UI setelah komputasi latar belakang selesai.

Penggunaan AsyncTask
    Untuk menggunakan kelas AsyncTask, definisikan subkelas AsyncTask yang menggantikan metode doInBackground(Params...) dan biasanya juga metode onPostExecute(Result)

Paremeter AsyncTask
Di subkelas AsyncTask, sediakan tipe data untuk tigas jenis parameter, yaitu:
1. "Params" menetapkan tipe parameer yang diteruskan ke doInBackground() sebagai larik.
2. "Progress" menetapkan tipe parameter yang diteruskan ke publishProgress() di Thread latar belakang. Selanjutnya dieruskan ke metode onProgressUpdate() di Thread Utama.
3. "Result" menetapkan tipe parameter yang dikembalikan doInBackground(). Dan secara otomatis diteruskan ke onPostExecute() di Thread Utama.

Tetapkan tipe data untuk setiap tipe parameter, atau gunakan kata Void jika tipe parameter tidak digunakan. Contohnya :

public class MyAsyncTask extends AsyncTas<String, Void, Bitmap>{}

Dalam deklarasi kelas ini:
→ "Params" adalah String, jadi MyAsyncTask memerlukan satu atau beberapa string sebagai parameter di doInBackground().
→ "Progress" adalah Void, jadi MyAsyncTask tidak akan menggunakan metode publishProgress() atau onProgressUpdate().
→ "Result" adalah Bitmap, jadi MyAsyncTask mengembalikan Bitmap di doInBackground(), yang diterukan kedalam onPostExecute().

Contoh AsynTask
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}

Tiga parameter yang digunakan pada contoh diatas,yaitu:
1. URL untuk parameter "Params". Tipe URL berarti anda bisa meneruskan sejumlah URL ke dalam panggilan, dan URL secara otomatis diteruskan ke metode doInBackground() secara larik.
2. Integer untuk tipe parameter "Progress"
3. Long untuk tipe parameter "Result".

Mengeksekusi AsyncTask
Seteleh anda mendefinisikan subkelas AsyncTask, buat instance-nya di Thread utama. Kemudian panggil execute() di instance, dengan meneruskan sejumlah parameter. Contohnya:
new DownloadFilesTask().execute(url1, url2, url3); // untuk mengeksekusi tugas DownloadFileTask

Membatalkan AsyncTask
Anda bisa membatalkan tugas kapan saja dari Thread apa pun dengan memanggil metode cancel():
⇒ Metode cancel() akan mengembalikan nilai false jika tugas tidak bisa dibatalkan, biasanya karena sudah diselesaikan secara normal. Jika tidak, cancel() akan mengembalikan nilai true.
⇒ Untuk mengetahui apakah tugas sudah dibatalkan, periksa nilai yang dikembalikan isCancelled() secara berkala dari doInBackground(Object[]).
⇒ Setelah tugas AsyncTask dibatalkan, onPostExecute() tidak akan digunakan setelah doInBackground() dikembalikan. Sebagai gantinya, onCancelled(Object) akan dipanggil cukup memanggil onCancelled() dan mengabaikan hasil.
⇒ Secara default, tugas yang sedang diproses boleh diselesaikan. Untuk memperbolehkan cancel() menyela Thread yang sedang mengesksekusi tugas, teruskan true untuk nilai mayInterruptltRunning.

Keterbatasan AsyncTask
AsyncTask tidak praktis untuk beberapa kasus penggunaan seperti berikut :
a. Perubahan pada konfigurasi perangkat menyebabkan masalah
    Bila konfigurasi perangkat berubah sewaktu AsyncTask berjalan, misal jika pengguna mengubah orientasi layar, aktivasi yang membuat AsyncTask akan dimusnahkan dan dimuat ulang. Metode AsyncTask tidak dapat mengakses aktivitas yang baru saja dibuat dan hasil AsyncTask tidak akan dipublikasikan.
b. Objek AsyncTask lama tetap ada, dan aplikasi anda bisa kehabisan memori
    Jika aktivitas yang membuat AsyncTask dimusnahkan, AsyncTask tidak akan dimusnahkan bersamanya. Misal, jika pengguna keluar dari aplikasi setelah AsyncTask dimulai, AsyncTask akan terus menggunakan sumber daya kecuali jika anda memanggil cancel().

Bila menggunakan AsyncTask :
1. Tugas singkat atau yang bisa disela.
2. Tugas yang tidak perlu untuk melaporkan kembali ke UI.
3. Tugas dengan prioritas rendah yang bisa ditinggalkan sebelum proses selesai.

Untuk semua situasi lainnya, gunakan AsyncTaskLoader. AsyncTaskLoader  adalah bagian dari kerangka kerja Loader yang akan kita bahas dibaawah ini :

C. Loader
    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. Gunakan kelas LoaderManager untuk satu atau beberap instance Loader dalam activity atau fragment. Gunakan initLoader() untuk melalukan inisialisasi dan mengaktifkannya. Biasanya, melalukan ini dalam metode onCreate() ativitas. Contohnya :

//prepare the loader. Either reconnect with an existing one,
//or start a new one.getLoaderManager().initLoader(0, null, this);

Jika anda menggunakan Library, buat panggilan ini menggunakan getSupportLoaderManager() sebagai ganti getLoaderManager(). Misalnya :

getSupportLoaderManager().initLoader(0, null, this);

Masukan panggilan ke initLoader() di onCreate() sehingga aktivitas bosa dihubungkan kembali ke loader yang sama bila konfigurasi berubah. Dengan cara itu, loader tidak kehilangan data yang sudah dimuatnya.

Memuat Ulang Loader
    Bila initLoader() menggunakan kembali loader yang ada, maka data yang telah dimuat loader akan diganti, namun kadang-kadang anda perlu menggantinya. 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.

Tentang metode restartLoader():
restartLoader() menggunakan argumen yang sama dengan initLoader().
⇒ restartLoader() akan memicu metode onCreateLoader().
⇒ Jika sudah ada loader dengan ID yang diberikan, restartLoader() akan memuali ulang loader yang diidentifikasi dan mengganti datanya.
⇒ Jika tidak ada loader dengan ID yang diberikan, restartLoader() akan memulai loader baru.

Callback LoaderManager
    Objek LoaderManager secara otomatis memanggil onStartLoading() saat membuat loader. Setelah itu, LoaderManager akan mengelola keadaan loader berdasarkan pada keadaan aktivitas dnan data. Untuk berinteraksi dengan loader, gunakan salah satu callback LoaderManager diaktivitas 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, disinilah anda biasanya ingin memindahkan data kedalam tampilan aktivitas.
⇒ Panggil onLoaderReset() bila loader yang dibuat sebelumnya sedang disetel ulang, sehingga datanya tidak tersedia. Disinilah 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 digunakan adalah AsyncTaskLoader. AsyncTaskLoader  menggunakan AsyncTask untuk menjalankan tugas pada Thread Pekerja.

D. 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.

Penggunaan AsyncTaskLoader  
    Untuk mendefinisikan subkelas AsyncTaskLoader , buat kelas yang memperluas AsyncTaskLoader <D>, dalam hal ini "D" adalah tipe data yang sedang anda muat.Contohnya 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 menruskannya ke panggilan untuk super().
→ Jika loader anda memerlukan informasi tambahan untuk melalukan pemuatan , konstruktor bisa mengambil argumen tambahan. Contoh konstruktor menggunakan sebuah istilah kueri :

public StringListLoader(Context context, String queryString){
    super(context);
    mQueryString = queryString;
}

Untuk melakukan pemuatan, gunakan metode pengganti loadInBackground(), akibat metode doInBackground() dari AsyncTask. Misal :

@Override
public List<String>loadInBackground(){
    List<String> data = new ArrayList<String>;
    //TODO: Load the data from the network or from a database
    return data;
}

Mengimplementasikan Callback
Gunakan konstruktor di callback onCreateLoader() LoaderManager, yang merupakan tempat membuat loader baru. Contoh menggunakan konstruktor StringListLoader:

@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(), disinilah bisa menampilkan hasil di UI. Contohnya :

publuc 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 dimusnahkan.
Bila menggunakan AsyncTaskLoader, data anda akan bertahan bila ada perubahan konfigurasi perangkat. Jika aktivitas anda dimusnahkan secara permanen, loader akan dimusnahkan bersamanya tanpa tugas yang menanti dan mengonsumsi sumber daya sistem.Loader juga memiliki manfaat lain, misalnya loader bisa memantau perubahan sumber data dan memuat ulang data jika terjadi perubahan.

Nah gimana sahabat blogger sudah paham materi tentang AsyncTask dan AsyncTaskLoader?? Yuk langsung ke implementasi konsepnya ke sebuah aplikasi Android Studio AsyncTaskDownload dibawah ini Tutorialnya, siapkan alat termpur PC atau Laptop yang mempunyai kapasitas RAM minimal 4GB.

Tutorial konsep AsyncTask dan AsynTask Loader pada pembuatan Aplikasi AsyncTaskDownload Android Studio

1. Buka aplikasi Android Studio IDE, kemudian buat project baru "Create New Project".


2. Pilih "Empty Activity" → "Next".


3. Configure Your Project

Keterangan :

Name AsyncTaskDownload atau bisa disesuaikan dengan keiginan anda.
Package name →  bisa default saja atau bisa juga diubah, disini saya menggunakan url blog saya lalu diikuti nama project AsyncTaskDownload.
Save Location → sesuaikan tempat penyimapan project anda.
Languange Java (karena pada artikel tutorial ini menggunakan pemrograman bahasa java).
Minimum SDKAPI 14Finish.

4. Maka akan muncul tampilan IDE Android Studio.

5. Buka lah file activity_main.xml, sebelum ke coding kita ubah terlebih dahulu Layout nya menjadi RelativeLayout, dengan langkah berikut :
→ Pertama pergi ke "Component Tree"


→ Kedua klik kanan pada "ConstraintLayout", lalu pilih "convert view..".


→ Ketiga, akan muncul pilihan beberapa layout, pilihlah "RelativeLayout" → "Apply".


Setelah diubah layoutnya, buka code file activity_main.xml dan tambahkan script seperti dibawah ini:


Dari script diatas tampilan Design + Blueprint akan menjadi seperti ini :

6. Selanjutnya kita buat fungsional pada tombol button agar dapat memproses dara, buka dan ubahlah script pada file MainActivity.java seperti dibawah ini :
package ryeyen08.blogspot.com.asynctaskdownload;
import android.Manifest;
import android.app.DownloadManager;
import android.content.Intent;
import android.content.pm.PackageManager;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import android.util.Log;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity implements OnClickListener {
public static final int download_progress = 0;
private String file_url = "http://adi.unggasid.com/wp-content/uploads/2021/01/Ringkasan-Tesis-Adi-Muhamad.pdf";
Button btn_download ;
ProgressDialog prgDialog;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_download = (Button) findViewById(R.id.button1);
btn_download.setOnClickListener(this);
}
@Override
public void onClick (View v){
if(ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED){
Log.i("Permission" , "Permission is Denied");
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},101);
}else{
new DownloadFileAsync().execute(file_url);
}
}
@Override
protected Dialog onCreateDialog(int id){
switch (id){
case download_progress :
prgDialog = new ProgressDialog(this);
prgDialog.setMessage("Downloading File...");
prgDialog.setIndeterminate(false);
prgDialog.setMax(100);
prgDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
prgDialog.setCancelable(false);
prgDialog.show();
return prgDialog;
default:
return null;
}
}
class DownloadFileAsync extends AsyncTask<String, Integer, String>{
@Override
protected void onPreExecute(){
showDialog(download_progress);
}
@Override
protected String doInBackground(String... aurl){
Log.i("testing", "url download : "+aurl[0]);
URL url = null;
int count;
try {
url = new URL(aurl[0]);
URLConnection conexion = url.openConnection();
conexion.connect();
Log.i("koneksi" , "koneksi berhasil");
int lengthOfFile = conexion.getContentLength();
Log.i("Ukuran File", "ukuran : "+String.valueOf(lengthOfFile));
InputStream input = new BufferedInputStream(url.openStream(),10*1024);
String fileName = conexion.getHeaderField("Content-Disposition");
if (fileName == null || fileName.length() < 1){
URL downloadUrl = conexion.getURL();
fileName = downloadUrl.getFile();
fileName = fileName.substring(fileName.lastIndexOf("/") +1);
}else{
fileName = URLDecoder.decode(fileName.substring(fileName.indexOf("filename= ")+9), "UTF-8");
fileName = fileName.replaceAll("\"", "");
}

OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory().getPath()
+"/Download/"+fileName);
byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress((int) ((total*100)/lengthOfFile));
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
} catch (Exception e){
e.printStackTrace();
Log.d("koneksi" , "koneksi gagal");
}
return null;
}
protected void onProgressUpdate(Integer... progress){
prgDialog.setProgress(progress[0]);
}
protected void onPostExecute(String result) {
dismissDialog(download_progress);
Toast.makeText(getApplicationContext(), "Download Complete. File in /sdcard/Download",
Toast.LENGTH_SHORT).show();
}
}
}

7. Kemudian kita membuat sebuah file dengan nama network_security_config.xml, dimana file ini digunakan agar aplikasi bisa mengakses url yang tanpa SSL (url https). File ini berupa file xml dan disimpan di folder res/xml, bagaimana caranya? ikuti langkah berikut :
→ Pertama buatlah sebuah Directory baru, klik kanan "res"→ pilih "New" → Pilih "Directory".

→ Kedua, akan muncul pop-up untuk menamai directory baru, masukan namanya "xml".

→ Ketiga, klik kanan folder xml → pilih "New" → pilih "XML" → lalu pilih "Values XML File".

→Keempat, akan muncul New Android Component maka masukan lah values file namenya "network_security_config".

→Kelima, karena file yang tadi dibuat masuk ke folder value maka pindahkan file network_security_config.xml dengan di drag ke folder xml. akan muncul tampilan dibawah ini pilih "Refaktor"


Setelah dipindahkan buka file network_security_config.xml dan ubahlah script nya menjadi seperti berikut :

8. Lalu setelah itu, untuk mendaftarkan komponen Intent Filter dan mendaftarkan permission akses interner & write external storage yang dibutuhkan maka buka file AndroidManifets.xml dan tambahkan beberapa script seperti pada gambar :

9. Terakhir coba jalankan aplikasinya di emulator dengan pilih "Run App", maka akan tampil seperti berikut:

    Pada gambar emulator nomor 2 Aplikasi akan meminta akses ke media penyimpanan anda, pilih lah Allow atau Izinkan selanjutnya di emultor nomor 3 progress download. Setelah berhasil akan ada pemberitahuan seperti pada emulator nomor 4. Selanjutnya coba cek di folder .../download/ menggunakan file manager seperti di emulator 5. Dan coba buka file hasil download tersebut yang terlihat di layer emulator 6.

Nah itu dia pembahasan konsep AsyncTask dan AsyncTaskLoader disertai tutorial pembuatan project nya, bagaimana apa sahabat ada kesulitan? jika ingin berdiskusi bersama bisa komentar dibawah atau hubungi lewat email. Semoga membantu sahabat blogger😀 Mohon maaf jika ada salah salah kata 🙏

Terimakasih ,, sampai ketemu di artikel yang lainnya ...

0 comments:

Posting Komentar