Pelajaran 7: Background Task
7.1: Membuat AsyncTask
Tugas 1: Menyiapkan Proyek SimpleAsyncTask
1.1 Membuat layout
Dengan ketentuan sebagai berikut
Berikut ini hasilnya:
Tugas 2: Membuat subkelas AsyncTask
2.1 Menjadikan AsyncTask Subkelas
1. Buat kelas Java baru bernama SimpleAsyncTask yang memperluas AsyncTask dan yang memerlukan tiga parameter tipe generik:
public class SimpleAsyncTask extends AsyncTask <Void, Void, String>{}
2. Definisikan variabel anggota mTextView.
3. Implementasikan konstruktor untuk AsyncTask yang memerlukan TextView dan menyetel mTextView ke yang
diteruskan dalam TextView:
public SimpleAsyncTask(TextView tv) {
mTextView = tv;
}
2.2 Mengimplementasikan doInBackground()
1. Tambahkan metode doInBackground() yang diperlukan. Letakkan kursor pada deklarasi kelas yang disorot, tekan Alt + Enter dan pilih metode Implement. Pilih doInBackground() dan klik OK:
@Override
protected String doInBackground(Void… voids) {
return null;
}
2. Implementasikan doInBackground() :
- Buat integer acak antara 0 dan 10
- Kalikan jumlahnya dengan 200
- Buat thread saat ini agar tertidur. (Gunakan Thread.sleep() ) dalam blok try/catch.
- Kembalikan String “Awake at last after xx milliseconds” (xx adalah jumlah milidetik saat aplikasi tertidur)
Berikut ini Kode solusinya:
@Override
protected String doInBackground(Void… voids) {
// Generate a random number between 0 and 10
Random r = new Random();
int n = r.nextInt(11);
// Make the task take long enough that we have
// time to rotate the phone while it is running
int s = n * 200;
// Sleep for the random amount of time
try {
Thread.sleep(s);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Return a String result
return “Awake at last after sleeping for ” + s + ” milliseconds!”;
}
2.3 Mengimplementasikan onPostExecute()
1. Implementasikan onPostExecute() untuk mengambil argumen String (yang Anda definisikan dalam parameter ketiga AsyncTask dan yang metode doInBackground() kembalikan) dan tampilkan string tersebut dalam TextView:
protected void onPostExecute(String result) {
mTextView.setText(result);
}
Tugas 3: Mengimplementasikan Langkah Terakhir
3.1 Implementasikan metode yang mulai dengan AsyncTask
1. Dalam file MainActivity.java file, tambahkan variabel anggota untuk menyimpan TextView.
private TextView mTextView;
2. Dalam metode onCreate() , inisialisasi mTextView ke TextView dalam UI.
3. Tambahkan kode ke metode startTask() untuk membuat instance SimpleAsyncTask , meneruskan TextView mTextView ke konstruktor.
4. Panggil execute() pada instance SimpleAsyncTask tersebut.
5. Perbarui TextView untuk menampilkan teks “Napping…”
public void startTask (View view) {
// Put a message in the text view
mTextView.setText(“Napping… “);
// Start the AsyncTask.
// The AsyncTask has a callback that will update the text view.
new SimpleAsyncTask(mTextView).execute();
}
3.2 Mengimplementasikan onSaveInstanceState()
1. Jalankan aplikasi dan klik tombol Start Task. Berapa lama aplikasi tertidur?
2. Klik tombol Start Task lagi, dan saat aplikasi tertidur, putar perangkat. Jika tugas latar belakang selesai sebelum Anda bisa memutar ponsel, coba lagi. Atau, Anda bisa memperbarui kode dan membuatnya tertidur untuk jangka waktu yang lebih lama.
3. Ganti metode onSaveInstanceState() dalam MainActivity untuk mempertahankan teks di dalam TextView saat aktivitas dimusnahkan:
outState.putString(TEXT_STATE, mTextView.getText().toString());
4. Ambil nilai TextView saat aktivitas dipulihkan dalam metode onCreate() .
// Restore TextView if there is a savedInstanceState
if(savedInstanceState!=null){
mTextView.setText(savedInstanceState.getString(TEXT_STATE));
}
7.2: Menghubungkan ke Internet dengan AsyncTask dan
AsyncTaskLoader
Tugas 1. Menjelajahi Books API
1.1 Mengirimkan Permintaan API Books
1. Buka Google APIs Explorer (bisa ditemukan di https://developers.google.com/apis-explorer/).
2. Klik Books API.
3. Temukan (Ctrl-F atau Cmd-F) books.volumes.list dan klik nama fungsi tersebut. Anda seharusnya bisa melihat
laman web yang mencantumkan berbagai parameter fungsi API Books yang melakukan penelusuran buku.
4. Dalam bidang q masukkan nama buku, atau sebagain nama buku. Parameter q adalah satu-satunya bidang yang diwajibkan.
5. Gunakan bidang maxResults dan printType untuk membatasi hasil ke 10 buku yang cocok yang dicetak.
6. Pastikan switch “Authorize requests using OAuth 2.0″ di bagian atas formulir dinonaktifkan. Klik Execute without OAuth di bagian bawah formulir.
7. Gulir ke bawah untuk melihat Permintaan dan Respons.
1.2 Menganalisis Respons API Books
1. Dalam bagian Respons, temukan nilai untuk kunci “title”. Perhatikan bahwa hasil ini memiliki nilai dan kunci tunggal.
2. Termukan nilai untuk kunci “authors”. Perhatikan bahwa kunci ini berisi larik nilai.
3. Dalam praktik ini Anda hanya akan mengembalikan judul dan penulis item pertama.
Tugas 2: Membuat “Who Wrote it?” Aplikasi
2.1 Membuat proyek dan antarmuka pengguna
1. Buat proyek aplikasi bernama Who Wrote it? dengan satu aktivitas, menggunakan Template Empty Activity.
2. Tambahkan elemen UI berikut di dalam file XML, menggunakan LinearLayout vertikal sebagai tampilan root—tampilan yang berisi semua tampilan lain di dalam file XML layout. Pastikan LinearLayout menggunakan
android:orientation=”vertical” :
3. Dalam file strings.xml, tambahkan sumber daya string berikut ini:
<string name=”instructions”>Enter a book name, or part of a
book name, or just some text from a book to find
the full book title and who wrote the book!</string>
<string name=”button_text”>Search Books</string>
<string name=”input_hint”>Enter a Book Title</string>
4. Buat metode bernama searchBooks() dalam MainActivity.java untuk menangani tindakan tombol onClick. Seperti pada semua metode onClick, yang satu ini memerlukan View sebagai parameter.
2.2 Menyiapkan Aktivitas Utama
1. Dalam MainActivity.java, buat variabel anggota untuk EditText, TextView penulis dan TextView judul.
2. Inisialisasi variabel ini dalam onCreate() .
3. Dalam metode searchBooks() , dapatkan teks dari widget EditText dan konversikan ke String , menetapkannya ke variabel string.
String queryString = mBookInput.getText().toString();
2.3 Membuat AsyncTask kosong
1. Buat kelas Java baru bernama FetchBook dalam aplikasi/java yang diperluas AsyncTask . AsyncTask memerlukan tiga argumen:
- Parameter masukan.
- Indikator kemajuan.
- Jenis hasil.
2. Implementasikan metode yang diperlukan, doInBackground()
3. Untuk menampilkan hasil dalam TextView, Anda harus memiliki akses ke TextView yang ada di dalam AsyncTask. Buat variabel anggota dalam FetchBook AsyncTask untuk dua TextView yang menunjukkan hasilnya, dan inisialisasi keduanya dalam konstruktor. Anda akan menggunakan konstruktor ini dalam MainActivity untuk meneruskan TextView ke AsyncTask.
Kode solusi untuk FetchBook:
public class FetchBook extends AsyncTask<String,Void,String>{
private TextView mTitleText;
private TextView mAuthorText;
public FetchBook(TextView mTitleText, TextView mAuthorText) {
this.mTitleText = mTitleText;
this.mAuthorText = mAuthorText;
}
@Override
protected String doInBackground(String… params) {
return null;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
2.4 Membuat kelas NetworkUtils dan membangun URI
1. Buat kelas Java baru bernama NetworkUtils dengan mengeklik File > New > Java Class dan hanya mengisi bidang “Name”.
2. Buat variabel LOG_TAG unik untuk digunakan di semua kelas NetworkUtils untuk membuat catatan log:
private static final String LOG_TAG = NetworkUtils.class.getSimpleName();
3. Buat metode statis baru bernama getBookInfo() yang mengambil String sebagai parameter (yang akan menjadi istilah penelusuran) dan mengembalikan String (respons String JSON dari API yang Anda periksa sebelumnya).
static String getBookInfo(String queryString){}
4. Buat dua variabel lokal berikut dalam getBookInfo() yang akan dibutuhkan nanti untuk membantu menyambungkan dan membaca data yang datang.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
5. Buat variabel lokal lain di akhir getBookInfo() untuk memasukkan respons mentah dari kueri dan mengembalikannya:
String bookJSONString = null;
return bookJSONString;
6. Buat konstanta anggota berikut dalam kelas NetworkUtils:
private static final String BOOK_BASE_URL = “https://www.googleapis.com/books/v1/volumes?”; // Base URI for the Books API
private static final String QUERY_PARAM = “q”; // Parameter for the search string
private static final String MAX_RESULTS = “maxResults”; // Parameter that limits search results
private static final String PRINT_TYPE = “printType”; // Parameter to filter by print type
7. Buat blok try/catch/finally skeleton dalam getBookInfo() . Di sinilah Anda akan membuat permintaan HTTP. Kode untuk membangun URI dan mengeluarkan kueri akan masuk ke dalam blok try. Blok catch digunakan untuk menangani masalah apa pun dengan membuat permintaan HTTP dan blok finally untuk menutup koneksi jaringan setelah Anda selesai menerima data JSON dan mengembalikan hasilnya.
try {
…
} catch (Exception ex) {
…
} finally {
return bookJSONString;
}
8. Bangun URI permintaan dalam blok try:
//Build up your query URI, limiting results to 10 items and printed books
Uri builtURI = Uri.parse(BOOK_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, queryString)
.appendQueryParameter(MAX_RESULTS, “10”)
.appendQueryParameter(PRINT_TYPE, “books”)
.build();
9. Konversi URI ke URL:
URL requestURL = new URL(builtURI.toString());
2.5 Membuat Permintaan
1. Dalam blok try metode getBookInfo() , buka koneksi URL dan buat permintaan.
urlConnection = (HttpURLConnection) requestURL.openConnection();
urlConnection.setRequestMethod(“GET”);
urlConnection.connect();
2. Baca respons menggunakan InputStream dan StringBuffer, lalu konversikan ke String :
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
/* Since it’s JSON, adding a newline isn’t necessary (it won’t affect
parsing) but it does make debugging a *lot* easier if you print out the
completed buffer for debugging. */
buffer.append(line + “\n”);
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
bookJSONString = buffer.toString();
3. Tutup blok try dan log pengecualiannya dalam blok catch.
catch (IOException e) {
e.printStackTrace();
return null;
}
4. Tutup kedua urlConnection dan variabel pembaca dalam blok finally:
finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5. Log nilai variabel bookJSONString sebelum mengembalikannya. Sekarang Anda sudah selesai dengan metode getBookInfo() .
Log.d(LOG_TAG, bookJSONString);
6. Dalam metode AsyncTask doInBackground() , panggil metode getBookInfo() , meneruskan istilah penelusuran yang Anda dapatkan dari argumen params yang diteruskan oleh sistem (ini adalah nilai pertama dalam larik params ). Kembalikan hasil dari metode ini dalam metode doInBackground() :
return NetworkUtils.getBookInfo(params[0]);
7. Sekarang setelah AsyncTask disiapkan, Anda perlu meluncurkannya dari MainActivity menggunakan metode
execute() . Tambahkan kode berikut ke metode searchBooks() dalam MainActivity.java untuk meluncurkan
AsyncTask:
new FetchBook(mTitleText, mAuthorText).execute(mQueryString);
8. Jalankan aplikasi Anda. Eksekusi penelusuran. Aplikasi Anda akan crash. Lihat Log untuk memeriksa apa yang menyebabkan kesalahan.
2.6 Menambahkan izin internet
1. Buka file AndroidManifest.xml.
2. Semua izin aplikasi harus diletakkan dalam file AndroidManifest.xml di luar tag <application> ;. Anda harus
memastikan untuk mengikuti urutan tempat tag didefinisikan dalam AndroidManifest.xml.
3. Tambahkan tag xml berikut di luar tag <application> :
<uses-permission android:name=”android.permission.INTERNET” />
<uses-permission android:name=”android.permission.ACCESS_NETWORK_STATE” />
4. Bangun dan jalankan aplikasi Anda lagi. Menjalankan kueri seharusnya menghasilkan string JSON dicetak ke Log.
2.7 Parse string JSON
1. Dalam onPostExecute() , tambahkan blok try/catch di bawag panggilan ke super .
2. Gunakan kelas JSON Java bawaan ( JSONObject dan JSONArray ) untuk mendapatkan larik JSON item hasil dalam blok try.
JSONObject jsonObject = new JSONObject(s);
JSONArray itemsArray = jsonObject.getJSONArray(“items”);
3. Iterasi melalui itemsArray , memeriksa judul dan informasi penulis setiap buku. Jika keduanya bukan null, keluar dari loop dan perbarui UI; jika tidak, terus periksa daftarnya. Dengan cara ini, hanya entri dengan judul dan penulis yang akan ditampilkan.
//Iterate through the results
for(int i = 0; i<itemsArray.length(); i++){
JSONObject book = itemsArray.getJSONObject(i); //Get the current item
String title=null;
String authors=null;
JSONObject volumeInfo = book.getJSONObject(“volumeInfo”);
try {
title = volumeInfo.getString(“title”);
authors = volumeInfo.getString(“authors”);
} catch (Exception e){
e.printStackTrace();
}
//If both a title and author exist, update the TextViews and return
if (title != null && authors != null){
mTitleText.setText(title);
mAuthorText.setText(authors);
return;
}
}
4. Jika tidak ada hasil yang memenuhi kriteria memiliki penulis dan judul yang valid, setel TextView judul untuk membaca “No Results Found”, dan hapus TextView authors .
5. Dalam blok catch, cetak kesalahan ke log, setel TextView judul ke “No Results Found”, dan hapus TextView authors .
Tugas 3. Mengimplementasikan praktik terbaik UI
3.1 Menyembunyikan Keyboard dan Memperbarui TextView
1. Menambahkan kode berikut ke metode searchBooks() untuk menyembunyikan keyboard saat tombol ditekan:
InputMethodManager inputManager = (InputMethodManager)
getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),
InputMethodManager.HIDE_NOT_ALWAYS);
2. Menambahkan satu baris kode di bawah panggilan untuk mengeksekusi tugas FetchBook yang mengubah TextView judul untuk menbaca “Loading…” dan menghapus TextView penulis.
3. Mengekstrak sumber daya String.
3.2 Mengelola status jaringan dan kasus bidang penelusuran kosong
1. Modifikasi metode searchBooks() untuk memeriksa kedua koneksi jaringan dan apakah ada teks dalam bidang
penelusuran sebelum mengeksekusi tugas FetchBook.
2. Perbarui UI dalam kasus tidak ada koneksi internet atau tidak ada teks dalam bidang penelusuran. Tampilkan
penyebab kesalahan dalam TextView.
Tugas 4. Migrasi ke AsyncTaskLoader
4.1 Membuat AsyncTaskLoader
1. Salin proyek WhoWroteIt, untuk mempertahankan hasil dari praktik sebelumnya. Ganti nama proyek yang disalin menjadi WhoWroteItLoader.
2. Buat kelas baru dalam direktori Java bernama BookLoader.
3. Buat agar kelas BookLoader memperluas AsyncTaskLoader dengan tipe berparameter. .
4. Pastikan Anda mengimpor loader dari Pustaka Dukungan v4.
5. Implementasikan metode yang diperlukan ( loadInBackground() ). Perhatikan kemiripan antara metode ini dan metode doInBackground() awal dengan AsyncTask.
6. Buat konstruktor untuk kelas baru .
4.2 Memodifikasi MainActivity
1. Tambahkan implementasi LoaderManager.LoaderCallbacks ke deklarasi kelas Aktivitas Utama, yang berparameter dengan tipe String :
public class MainActivity extends AppCompatActivity
implements LoaderManager.LoaderCallbacks<String>{
2. Implementasikan metode yang diperlukan: onCreateLoader(), onLoadFinished(), onLoaderReset() . Letakkan kursor teks pada baris tanda tangan kelas dan masukkan Alt + Enter (Option + Enter di Mac). Pastikan semua metode dipilih.
7.3: Penerima Siaran
Tugas 1. Menyiapkan Proyek PowerReceiver
1.1 Membuat Proyek
1. Membuat proyek baru bernama PowerReceiver, menerima opsi default dan menggunakan template Empty.
2. Membuat Penerima Siaran baru. Pilih nama paket dalam Tampilan Proyek Android dan buka File > New > Other > Broadcast Receiver.
3. Beri nama kelasnya CustomReceiver dan pastikan “Exported” dan “Enabled” dicentang.
4. Buka file manifes Android. Ingat bahwa Android Studio secara otomatis membuat tag <receiver> dengan opsi terpilih sebagai atribut. BroadcastReceivers juga bisa didaftarkan secara program, tetapi lebih mudah mendefinisikannya dalam manifes.
1.2 Mendaftarkan Penerima untuk siaran sistem
1. Dalam file AndroidManifest.xml, tambahkan kode berikut di antara tag <receiver> untuk mendaftarkan Penerima Anda untuk Intent sistem:
<intent-filter>
<action android:name=”android.intent.action.ACTION_POWER_CONNECTED”/>
<action android:name=”android.intent.action.ACTION_POWER_DISCONNECTED”/>
</intent-filter>
1,3 Mengimplementasikan onReceive() dalam BroadcastReceiver
1. Buka file CustomReceiver, dan hapus implementasi default dalam metode onReceive() .
2. Dapatkan tindakan dari intent dan simpan dalam variabel String bernama intentAction :
@Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
}
3. Buat pernyataan switch dengan string intentAction , agar aplikasi dapat menampilkan pesan toast yang berbeda
untuk setiap tindakan spesifik yang didaftarkan kepada penerima:
switch (intentAction){
case Intent.ACTION_POWER_CONNECTED:
break;
case Intent.ACTION_POWER_DISCONNECTED:
break;
}
4. Inisialisasi variabel String bernama toastMessage sebelum pernyataan switch , dan jadikan nilainya null agar
bisa disetel tergantung pada tindakan siaran yang Anda terima.
5. Tetapkan toastMessage ke “Power connected!” jika tindakannya ACTION_POWER_CONNECTED , dan “Power disconnected!”
jika ACTION_POWER_DISCONNECTED . Ekstrak sumber daya string.
6. Tampilkan pesan toast untuk durasi pendek setelah pernyataan switch:
Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();
7. Jalankan aplikasi Anda. Setelah dipasang, cabut perangkat. Proses ini mungkin memakan beberapa waktu saat
pertama kali dilakukan, tetapi toast pasti ditampilkan setiap kali Anda mencolokkan atau mencabut perangkat.
1.4 Membatasi Penerima Siaran
1. Silakan coba: tutup aplikasi, colok dan cabut perangkat.
Pesan toast tetap ditampilkan!
2. Agar penerima siaran hanya aktif ketika aplikasi ditampilkan, aktifkan penerima dalam onStart() dan nonaktifkan
dalam onStop() .
3. Buat dua variabel anggota: PackageManager dan ComponentName.
4. Inisialisasi keduanya di onCreate() .
Inisialisasi PackageManager dengan getPackageManager() . Konstruktor untuk ComponentName memerlukan konteks
aplikasi dan nama kelas komponen:
mReceiverComponentName = new ComponentName(this, CustomReceiver.class);
mPackageManager = getPackageManager();
5. Ganti onStart() dan onStop() :
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onStop() {
super.onStop();
}
6. Panggil setComponentEnabledSetting() di PackageManager dalam onStart() . Teruskan nama Komponen, konstanta
PackageManager.COMPONENT_ENABLED_STATE_ENABLED , dan bendera DONT_KILL_APP :
mPackageManager.setComponentEnabledSetting
(mReceiverComponentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
7. Dalam onStop() , gunakan PackageManager untuk menonaktifkan CustomReceiver, menggunakan konstanta
PackageManager.COMPONENT_ENABLED_STATE_DISABLED :
mPackageManager.setComponentEnabledSetting
(mReceiverComponentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
Tugas 2. Mengirimkan dan Menerima Siaran Khusus
2.1 Mendefinisikan string Tindakan Siaran khusus
1. Buat variabel String konstan dalam MainActivity dan kelas CustomReceiver untuk digunakan sebagai Tindakan
Intent Siaran (ini adalah string tindakan khusus):
private static final String ACTION_CUSTOM_BROADCAST =
“com.example.android.powerreceiver.ACTION_CUSTOM_BROADCAST”;
2.2 Tambahkan Tombol “Send Custom Broadcast”
1. Dalam file activity_main.xml, tambahkan tampilan Tombol
2. Ekstrak sumber daya string.
3. Buat stub untuk metode sendCustomBroadcast() : Klik pada nama metode onClick. Tekan Alt (Option untuk
pengguna Mac) + Enter dan pilih ‘Create ‘sendCustomBroadcast(View)’ dalam ‘MainActivity’.
2.3 Mengimplementasikan sendCustomBroadcast()
1. Dalam metode sendCustomBroadcast() di MainActivity, buat Intent baru, dengan string tindakan khusus sebagai
argumen.
Intent customBroadcastIntent = new Intent(ACTION_CUSTOM_BROADCAST);
2. Kirimkan siaran menggunakan kelas LocalBroadcastManager:
LocalBroadcastManager.getInstance(this).sendBroadcast(customBroadcastIntent);
2.4 Mendaftarkan Siaran Khusus
1. Buat variabel anggota di MainActivity untuk Penerima dan inisialisasi member tersebut:
private CustomReceiver mReceiver = new CustomReceiver();
2. Dalam onCreate() , dapatkan instance LocalBroadcastManager dan daftarkan penerima dengan tindakan intent
khusus:
LocalBroadcastManager.getInstance(this)
.registerReceiver(mReceiver, new IntentFilter(ACTION_CUSTOM_BROADCAST));
3. Ganti metode onDestroy() dan berhenti mendaftarkan penerima dari LocalBroadcastManager :
@Override
protected void onDestroy() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
super.onDestroy();
}
2.5 Merespons Siaran Khusus
1. Dalam onReceive() kelas CustomReceiver, tambahkan pernyataan case untuk Tindakan Intent khusus.
2. Modifikasi pesan toast ke “Custom Broadcast Received”, ekstrak ke dalam strings.xml dan panggil
custom_broadcast_toast (tekan Alt + Enter atau Option + Enter di Mac dan pilih extract string resource):
case ACTION_CUSTOM_BROADCAST:
toastMessage = context.getString(R.string.custom_broadcast_toast);
break;
Leave a Reply