Dasar Pemrograman Android PDF
Dasar Pemrograman Android PDF
3.1
Latar Belakang
Perkembangan aplikasi Android saat ini berkembang dengan pesat. Bermacam-macam
aplikasi Android gratis ataupun bayar dapat kita install di handphone (smartphone) berbasis
sistem operasi Android. Banyaknya
sekarang dan masa yang akan datang membuka peluang yang sangat menjanjikan bagi siapa saja
yang mau untuk menjadi pembuat atau pengembang aplikasi Android. Namun kebanyakan dari
pemilik smartphone saat ini hanya sebagai pengguna aplikasinya saja. Sudah saatnya sekarang
ini kita Putra Putri Bangsa Indonesia membuat atau mengembangkan aplikasi Android dan
menunjuk ke pada dunia bahwa kita mampu bersaing secara global, salah satunya dengan
membuat atau mengembangkan aplikasi Android, atau minimal aplikasinya bisa digunakan
sendiri. Oleh karena itu, tutorial ini dibuat untuk khusunya bagi siapa saja yang ingin menjadi
pembuat atau pengembang aplikasi Android dan umumnya bagi yang ingin menambah wawasan
tentang Android.
Untuk memulai pemrograman Android, pengetahuan dan pemahaman akan dasar dari
pemrograman Android tersebut sangatlah penting. Pemahaman yang dimaksud seperti
memahami mekanisme kerja komponen dalam sistem operasi Android dan bagaimana
menggunakan komponen
pengetahuan dan pemahaman tersebut kita ibarat kapal yang berlayar tanpa membawa peta.
Pada Tutorial ini akan membahas tentang struktur, mekanisme dan contoh program dari
setiap komponen yang ada di pemrograman Android. Materi yang akan dibahasa diantaranya
pengenalan dasar widget view (Text Control, Button, Check Box, Radio Button,Lis t View, Grid
View,Spinner, Date and Time), Layout, Adapter, Menu, Dialog, dan Animasi.
3.2
Tujuan
Setelah mempelajari tutorial ini, pembaca diharapkan dapat:
Page 61
c. Mengetahui dan memahami mekanisme kerja komponen dalam sistem operasi Android.
d. Memahami dan dapat menggunakan Widget View, Layout, Adapter, Menu, Dialog dan
Animasi.
e. Dapat menggunakan komponen secara efektif dalam membuat aplikasi di Android.
f. Dapat membuat program sederhana dengan memanfaatkan komponen yang ada pada aplikasi
Android.
3.3
dikompilasi beserta dengan data dan file sumber yang dibutuhkan oleh aplikasi yang
digabungkan oleh tool aapt ke dalam paket Android, dan hasilnya berupa file archive berekstensi
.apk. File inilah yang di distribusikan atau diunduh pengguna dan menginstalnya ke dalam
perangkat mobile. Semua kode yang ada di dalam sebuah file berekstensi .apk dianggap sebagai
sebuah aplikasi. Dalam banyak hal, setiap aplikasi Android hidup di dalam dunianya sendiri:
a.
Secara default, setiap aplikasi berjalan pada proses Linuxnya masing-masing. Android
memulai prosesnya ketika kode yang ada di dalam aplikasi akan dieksekusi, dan akan
mengakhirinya ketika proses itu tidak lagi diperlukan(system resources akan digunakan oleh
aplikasi lain).
b.
Setiap proses mempunyai virtual machine(VM) masing-masing, sehingga kode aplikasi akan
dipisahkan dari aplikasi yang lainnya.
c.
Secara default, setiap aplikasi diberikan sebuah user ID Linux yang unik. Aturan
penggunaan telah ditentukan sedemikian rupa sehingga hanya pengguna yang berhak saja
yang dapat mengakses dan menggunakan aplikasi tersebut walaupun ada beberapa cara
untuk mengekspor sebuah aplikasi ke dalam aplikasi lainnya.
User ID yang sama juga dapat digunakan oleh dua buah aplikasi sehingga aplikasi tersebut
dapat melihat file yang ada di kelolah oleh kedua aplikasi tersebut. User ID dapat mengatur dua
aplikasi, sehingga kedua aplikasi tersebut dapat saling berbagi file dan virtual machine untuk
menghemat system resources.
Page 62
3.4
Komponen Aplikasi
Fitur utama dari Android adalah sebuah aplikasi dapat menggunakan elemen dari aplikasi
lainnya (apabila diizinkan). Contohnya, jika aplikasi ditugaskan untuk menampilkan daftar
gambar yang dapat bergulir, maka aplikasi yang lain dapat menggunakannya untuk menampilkan
di dalam aplikasi tersebut. Fungsi yang sama dapat dipanggil di dalam dua aplikasi tanpa harus
membuatnya lagi. Aplikasi Android tidak mempunyai single entry point di dalamnya (contohnya,
tidak ada fungsi main()). Namun, Android mempunyai komponen penting yang dapat di
instantiate dan dijalankan oleh sistem apabila dibutuhkan. Ada empat macam komponen, yaitu:
a. Activities
Sebuah activity menyajikan sebuah user interface visual yang berfokus pada kegiatan dari
user. Sebuah aplikasi dapat terdiri dari satu atau beberapa activity. Ragam dan banyaknya
activity tersebut tergantung pada aplikasi dan perancangannya. Umumnya, sebuah activity
ditugaskan sebagai activity pertama yang akan tampil ketika aplikasi dijalankan, kemudian
dilanjutkan oleh activity berikutnya.
Contohnya, sebuah aplikasi dapat menyajikan daftar menu item atau menampilkan gambar
beserta keterangan yang dipilih oleh user. Sebuah aplikasi pengiriman teks bisa mempunyai
sebuah activity yang menampilkan daftar kontak untuk mengirim pesan, activity kedua
adalah menulis pesan ke kontak yang telah dipilih, dan activity yang lain adalah
menampilkan pesan lama atau mengubah pengaturan pesan. Walaupun activity tersebut
bekerja bersama pada sebuah user interface, namun setiap activity tidak saling bergantung
satu sama lain. Setiap activity diimplementasikan sebagai turunan (subclass) dari class
utama.
b. Services.
Servis adalah sebuah komponen aplikasi yang dapat melakukan operasi panjang yang
berjalan di background dan tidak menyediakan sebuah tampilan. Komponen aplikasi yang
lain dapat memulai sebuah servis dan terus berjalan di background meskipun pengguna
berpindah ke aplikasi lain. Sebagai tambahan, sebuah komponen dapat mengikat ke sebuah
services dan bahkan melakukan komunikasi antar proses (interprocess communication/IPC).
Sebagai contoh, sebuah services dapata menangani traksaksi jaringan, memutar musik,
Dasar Pemrograman Android
Page 63
melakukan file I/O, atau berinteraksi dengan sebuah content provider semuanya berjalan di
background.
Pada dasarnya sebuah services memiliki dua bentuk :
a. Started
Sebuah services started ketika sebuah komponen aplikasi (misalnya activity)
memulainya dengan memanggil startService(). Sekali dimulai, sebuah services
dapat berjalan di background tanpa batas, bahkan jika komponen yang telah berjalan di
hancurkan. Biasanya, sebuah services yang telah berjalan akan melakukan operasi
tunggal dan tidak mengembalihan sebuah hasil ke pemanggil. Sebagai contoh,
mengunduh atau mengunggah sebuah file melalui jaringan. Ketika operasi berjalan,
services harus berhenti dengan sendirinya.
b. Bound
Sebuah services bound ketika sebuah komponen aplikasi mengikat kepadanya dengan
memanggil bindService(). Sebuah bound services menawarkan sebuah antarmuka
klien-server yang memungkinkan komponen untuk berinteraksi dengan services,
mengirimkan permintaan, memperoleh hasil dan bahkan melakukan seluruh proses
dengan interprocess communication(IPC). Sebuah bound services hanya berjalan selama
komponen aplikasi lain terikat kepadanya. Banyak komponen dapat terikat kepada
services sekali, tetapi ketika seluruhnya melepaskan ikatan, services akan dihancurkan.
Sebuah services dapat melakukan keduanya, services dapat dimulai dan juga
memungkinkan mengikat, dengan mengimplementasikan sepasang method callback:
onStartCommand() untuk memungkin komponen memulai services dan onBind()
untuk memungkinkan mengikatnya.
Terlepas dari apakah aplikasi dijalankan, terikat, atau keduanya, komponen aplikasi dapat
menggunakan services ini (bahkan dari aplikasi terpisah), dengan cara yang sama setiap
komponen dapat menggunakan suatu activity dengan memulainya menggunakan sebuah
Intent. Services dapat dideklarasikan sebagai private di file manifest, dan membatasi
akses dari aplikasi lain. Bagian ini akan dibahas lebih pada sesi Mendeklarasikan
Services di Manifest
Page 64
The Basic
Sebuah services dapat dibuat dengan membuat sebuah subclass dari Service. Pada
pengimplementasian, dibutuhkan beberapa method callback yang menangani aspek kunci dari
siklus hidup services dan menyediakan sebuah mekanisme untuk komponen mengikat ke
services ini, jika sesuai. Method callback yang paling penting untuk di override adalah :
a. onStartCommand()
Sistem akan memanggil method ini ketika komponen lain seperti sebuah activity,
meminta service untuk dimulai dengan memannggil startService(). Sekali method
ini dieksekusi, services akan dimulai dan dapat berjalan di background tanpa batas. Jika
ini diterapkan, maka services harus di hentikan ketika tugasnya telah selesai dengan
memanggil stopSelf() atau stopService().
b. onBind()
Sistem memanggil method ini ketika komponen lain ingin mengikat dengan services
(misalnya melakukan RPC), dengan memanggil bindService(). Pada saat Anda
menerapkan method ini, Anda harus menyediakan sebuah antarmuka yang digunakan
klien untuk berkomunikasi dengan services, dengan mengembalikan Ibinder. Anda
harus selalu menerapkan method ini, tapi jika Anda tidak mengizinkan binding, makan
Anda harus mengembalikan null.
c. onCreate()
Sistem memanggil method ini ketika services pertama kali dibuat, untuk melakukan satu
kali prosedur setup (sebelum memanggil onStartCommand() atau onBind() yang lain).
Jika services telah berjalan, method ini tidak akan dipanggil.
d. onDestroy()
Sistem memanggil method ini ketika services tidak lagi digunakan dan akan dihancurkan.
Services Anda harus menerapkan ini untuk membersihkan berbagai resouces seperti
threads, registered listener, receivers, dan lain-lain. Method ini merupakan panggilan
terakhir yang diterima oleh services.
Jika sebuah komponen di mulai dengan memanggil startService() (yang merupakan hasil
pemanggilan onStartCommand()), kemudian services akan tetap berjalan hingga berhenti
Page 65
kepadanya. Sekali layanan tidak terikat dengan semua klien, sistem akan menghancurkannya.
Sistem Android akan force-stop sebuah services hanya jika memory rendah dan harus
memulihkan sumber daya sistem untuk activity yang menjadi fokus pengguna. Jika services
terikat dengan sebuah activity yang menjadi fokus pengguna, services tersebut memiliki
kemungkinan kecil untuk di kill dan jika services di deklarasikan untuk berjalan di depan latar,
maka services tersevut hampir tidak akan di kill.
Ada atribut lain yang dapat Anda masukkan ke dalam elemen <service> untuk menentukan
properti, seperti permissions untuk memulai services dan menentukan proses yang harus di
jalankan oleh services.
Atribut android:name merupakan atribut yang dibutuhkan, atribut ini menentukan nama
dari services. Ketika Anda mempublish aplikasi, Anda tidak diperkenankan untuk mengubah
nama ini, karena jika diubah akan menyebabkan merusak beberapa fungsi yang digunakan oleh
intents yang mengacu kepada services tersebut. Sama seperti activity, sebuah services dapat
mendefinisikan intent filters yang mengizinkan componen lain untuk meminta services
menggunakan implicit intents. Dengan mendeklarasikan intent filter, komponen dari berbagai
aplikasi yang terinstal di handset pengguna dapat menjalankan services Anda jika services
Dasar Pemrograman Android
Page 66
tersebut mendeklarasikan sebuah intent filter yang sesuai dengan intent dari aplikasi lain yang
dilewatkan ke startService().
Creating a Started Service
Sebuah started services merupakan salah satu komponen starts dengan memanggil
startService(),
sebuah services di jalankan, services tersebut memiliki siklus hidup yang independen dan dapat
berjalan di belakang layar tanpa batas, bahkan jika komponen yang berjalan mulai hancur.
Dengan demikian, services harus berhenti sendiri ketika tugasnya dilakukan dengan memanggil
stopSelf(),
Sebuah komponen aplikasi seperti sebuah activity dapat memullai services dengan memanggil
startService()
dan melewatkan sebuah Intent yang menentukan services dan termasuk data
yang digunakan oleh services. Services menerima Intent ini dalam method onStartComand().
Misalnya, suatu kegiatan perlu menyimpan data ke database online. Activity dapat
menjalankan sebuah services pendamping dan mengirimkan data yang akan disimpan dengan
melewatkan
intent()
onStartCommand(),
untuk
startService().
Services
menerima
intent
di
Page 67
Sesi berikut menjelaskan bagaimana menimplementasikan services menggunakan salah satu dari
class tersebut.
b. Membuat sebuah work queue yang melewatkan sebuah intent pada suatu waktu ke
penerapan onHandleIntent(), sehingga Anda tidak perlu mengkhawatirkan multithreading.
c. Menghentikan services setelah semua request ditangani, sehingga tidak perlu memanggil
stopSelf().
Page 68
Jika akan meng override method callback, seperti onCreate(), onStartCommand() atau
onDestroy(),
Selain onHandleIntent(), method yang tidak dibutuhkan untuk memanggil super class
adalah onBind() (tapi dibutuhkan jika services mengizinkan binding).
Page 69
Page 70
deliver the
// start ID so we know which request we're stopping when we finish
the job
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
mServiceHandler.sendMessage(msg);
// If we get killed, after returning from here, restart
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// We don't provide binding, so return null
return null;
}
@Override
public void onDestroy() {
Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
}
}
Page 71
digunakan untuk media players (atau services yang serupa) yang tidak mengeksekusi perintah,
tetapi berjalan tanpa batas dan menunggu sebuah pekerjaan.
START REDELIVER INTENT
Starting a Service
Sebuah services dari activity atau komponen aplikasi lain dapat dijalankan dengan
melewatkan sebuah intent ke startService(). Sistem Android memanggil method
onStartCommand()
langsung).
Sebagai contoh, sebuah activity dapat memulai contoh services pada sesi sebelumnya
(HelloService) menggunakan sebuah explisit intent dengan startService():
Intent intent = new Intent(this, HelloService.class);
startService(intent);
kemudian memanggil onStartCommand(). Jika services juga tidak menyediakan binding, intent
dikirimkan dengan startService() merupakan satu-satunya mode komunikasi antara
komponen aplikasi dan services. Akan tetapi jika anda ingin services mengirimkan nilai kembali,
kemudian klien yang dimulai servicesnya dapat membuat sebuah PendingIntent untuk broadcast
(dengan getBroadcast()) dan mengirimkan ke services dalam Intent yang servicesnya dimulai.
Services dapat menggunakan broadcast untuk mengirimkan hasil.
Berbagai request untuk memulai services menghasilkan berbagai panggilan yang saling
berkaitan ke onStartCommand(). Akan tetapi, hanya satu permintaan untuk menghentikan
services yang dibutuhkan untuk menghentikannya (stopSelf() atau stopService()).
Dasar Pemrograman Android
Page 72
Stopping a Service
Sebuah started services harus mengelola siklus hidupnya. Sistem tidak menghentikan atau
menghancurkan services kecuali recover memori sistem dan services diteruskan setelah
onStartCommand()
stopSelf() atau
Ketika ada permintaan untuk berhenti dengan stopSelf() atau stopService(), sistem akan
langsung menghancurkan services.
Akan tetapi, jika services menangani beberapa permintaan untuk onStartCommand()
secara bersamaan, maka services tersebut tidak harus dihentikan setelah selesai memproses
request awal, karena bisa saja ada request baru yang diterima (berhenti pada akhir request
pertama akan menghentikan request selanjutnya). Untuk menghindari masalah ini, bisa
digunakan dengan perintah stopSelf(int) untuk memastikan bahwa request untuk
menghentikan services selalu berdasarkan start request terbaru. Artinya, ketika stopSelf(int)
dipanggil,
anda
akan
onStartCommand()) ke
melewatkan
ID
dari
start
request
(startId
dikirimkan
ke
stop request yang sesuai. Kemudian jika services menerima start request
baru sebelum memanggil stopSelf(int), kemudian ID tidak cocok dan services tidak akan
dihentikan.
Page 73
Biasanya pemberitahuan menggunakan status bar merupakan teknik terbaik ketika beberapa
background work telah selesai (seperti download file telah selesai) dan pengguna dapat
melakukan tindakan padanya. Ketika pengguna memilih pemberitahuan dari tampilan,
pemberitahuan dapat memulai sebuah activity (seperti melihat file yang telah didownload)
Panduan membuat pemberitahuan berupa Toast ataupun Status Bar akan dibahas tersendiri.
Page 74
Kemudian, mungkin ketika pengguna ingin melakukan kontrol atas pemutar musik atau
mendapatkan informasi tentang lagu saat ini, suatu activity dapat mengikat ke services dengan
memanggil bindService(). Dalam kasus seperti ini, stopService() atau stopSelf() tidak
benar-benar menghentikan layanan tersebut hingga semua klien tidak terikat.
Implementing the lifecycle callbacks
Seperti activity, services memiliki method callback yang dapat diimplementasikan untuk
memonitor perubahan pada satus services dan melakukan pekerjaan pada waktu yang sesuai. Berikut
adalah demonstrasi dari skeleton services untuk setiap siklus hidup method:
public class ExampleService extends Service {
int mStartMode;
// indicates how to behave if the service is
killed
IBinder mBinder;
// interface for kliens that bind
boolean mAllowRebind; // indicates whether onRebind should be used
@Override
public void onCreate() {
// The service is being created
Page 75
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// The service is starting, due to a call to startService()
return mStartMode;
}
@Override
public IBinder onBind(Intent intent) {
// A klien is binding to the service with bindService()
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
// All kliens have unbound with unbindService()
return mAllowRebind;
}
@Override
public void onRebind(Intent intent) {
// A klien is binding to the service with bindService(),
// after onUnbind() has already been called
}
@Override
public void onDestroy() {
// The service is no longer used and is being destroyed
}
}
Dengan mengimplementasikan method ini, dan dapat memonitor dua perulangan bersarang dari
siklus hidup services:
a. Entire lifetime dari services terjadi antara waktu pemanggilan onCreate() dan waktu
pengembalian onReturns(). Seperti sebuah activity, sebuah services melakukan inisial
setup pada onCreate() dan melepaskan semua sumber daya yang tersisa pada
onDestroy().
Page 76
Jika services dimulai, active lifetime diakhiri pada waktu yang sama dengan entire
lifetime (services ini akan tetap aktif bahakan setelah
onStartCommand
dikembalikan). Jika services terikat, active lifetime akan diakhiri ketika onUnbind()
dikembalikan.
Gambar diatas mengilustrasikan method calback untuk sebuah services. Meskipun gambar
diatas services terpisah yang dibuat oleh startService() dan oleh bindService(), perlu
diingat bahwa services apapun, tidak peduli bagaimana dimulai, berpotensi dapat mengizinkan
klien untuk terikat pada services tersebut. Sehingga sebuah services yang dimulai dengan
onStartCommand()
c. Content providers
Sebuah content provider mengatur sharing aplikasi sehingga dapat digunakan oleh aplikasi
lainnya. Data tersebut dapat disimpan di file system, dalam sebuah database SQLite, di
Dasar Pemrograman Android
Page 77
website,
atau
dalam
ContentProvider
bentuk
untuk
lain.
Content
provider
mengimplementasikan
akan
meng-extend
serangkaian
method
class
yang
memungkinkan aplikasi lain untuk mengambil dan menyimpan data sesuai dengan yang
dikendalikannya. Namun, aplikasi tidak memanggil method ini secara langsung melainkan
dengan menggunakan object class Content Resolver dan memanggil method di dalamnya.
Contoh content provider Android yaitu pengaturan informasi kontak user dan aplikasi
NotePad untuk menyimpan catatan.
Kebanyakan aplikasi memiliki data yang hanya akan diakses oleh aplikasi tersebut. Bahkan
oleh OS Android, aplikasi lain tidak dapat membaca maupun menulis ke data pada aplikasi
tersebut. Akan tetapi, pada beberapa aplikasi membutuhkan data yang biasa untuk dibagi ke
aplikasi lain. Aplikasi lain diharapkan dapat menulis dan membaca pada data yang dibuat oleh
aplikasi tersebut. Contoh data ini adalah data informasi Kontak. Content Provider merupakan
penyimpanan dan pengambil data serta membuatnya dapat diakses oleh semua aplikasi.
Ketika diinginkan pembuatan data public maka terdapat dua pilihan yang dapat digunakan
yaitu membuat Content Provider sendiri atau menambahkan data ke Content Provider yang ada.
Seluruh Content Provider mengimplementasikan interface bersama untuk melakukan query ke
provider dan mendapatkan kembaliannya serta untuk menambahkan, mengubah dan menghapus
data. Content Provider yang telah tersedia pada sistem Android dapat dilihat pada tabel xx.
Content Provider
Data
Browser
CallLog
Contacs
Contact details
MediaStore
Settings
Page 78
ContentResolver
Kelas ContentResolver menyediakan akses aplikasi ke content. Kelas ini merupakan
interface yang biasa digunakan oleh klien untuk mengakses content secara tidak langsung.
ContentResolver didapatkan dengan memanggil method getContentResolver() dari dalam
Activity atau komponen aplikasi lainnya.
ContentResolver cr = getContentResolver();
Setelah didapat objek ContentResolver maka dapat digunakan method-method dari objek
tersebut untuk berinteraksi dengan Content Provider yang diinginkan. Ketika query dimulai,
maka Android akan mengidentifikasi Content Provider target query, memastikannya ada dan
berjalan. Sistem akan memulai seluruh objek ContentProvider tetapi dapat berkomunikasi
dengan objek ContentResolver beberapa aplikasi yang berbeda dan proses. Interaksi antara
proses ditangani oleh kelas ContentResolver dan ContentProvider.
Query ke Content Provider
Sama seperti bab sebelumnya, Query untuk Content Provider akan mengembalikan objek
cursor. Untuk melakukan query yang dibutuhkan: URL mengidentifikasi provider, nama dari
kolom yang diambil, dan jenis data yang akan diambil. Dalam melakukan query dapat
menggunakan method ContentRevolver.query() atau Activity.manageQuery(). Kedua
method ini akan mengembalikan objek cursor. Walau demikian, managedQuery() akan
mengakibatkan activity untuk mengelola life cycle dari cursor. Pengaturan ini akan menangani
ketika
activity
pause,
dan
meng-query
Activity.startManagingCursor()
kembali
ketika
activity
restart.
Method
Apabila activity dihentikan secara otomatis akan memanggil deactive() pada cursor yang
diberikan. Jika Activity restart, maka akan memanggil requery dan ketika activity dihancurkan
maka semua cursor yang ada akan ditutup secara otomatis.
Argumen pertama query() atau menagedQuery() adalah URI dari provider yaitu
CONTENT_URI konstan yang mengidentifikasi ContentProvider tertentu dan kumpulan data.
Untuk membatasi query hanya satu record, dengan menambahkan nilai_id untuk URI dengan
menempatkan string yang cocok dengan ID sebagai segmen terakhir di bagian URI. Misalnya,
Dasar Pemrograman Android
Page 79
./9.
Untuk mempermudah
yang
dianggap
penting.
Setiap
receiver
meng-extend
class
Broadcast receiver tidak menampilkan user interface. Namun, akan memulai sebuah activity
sebagai respon atas pemberitahuan yang diterima. Atau menggunakan NotificationManager
untuk memperingatkan pengguna. Notifikasi akan menarik perhatian user dengan berbagai
cara seperti: membuat backlight berkedap kedip, menggetarkan perangkat, memainkan suara
notifikasi, dan sebagainya. Menempatkan ikon yang tetap pada status bar yang dapat diakses
dan pesannya dapat dibaca langsung oleh user.
Page 80
mengembalikan hasil). Contohnya, jika sebuah activity untuk mengambil foto dijalankan,
maka kemungkinan user ingin agar foto yang baru saja diambil bisa ditampilkan.
b. Sebuah service dijalankan (atau diinstruksikan pada service yang sedang berjalan) dengan
cara melewatkan sebuah object intent ke dalam method startService(). Android akan
memanggil service onStart() dan melewatkan object intent.
Sebuah intent juga dapat dilewatkan ke dalam method bindService() untuk menjalin
koneksi yang sedang berlangsng di antara component yang dipanggil dan service yang dituju.
c. Aplikasi dapat mengirimkan broadcast dengan cara melewatkan sebuah obyek intent ke
dalam
method
sendBroadcast(),
sendOrdered-Broadcast(),
dan
menampilkan
content
provider
dengan
cara
memanggil
query()
pada
ContentResolver.
activity
lainnya
(apabila
dijalankan
dengan
Page 81
b.
c.
d.
API library yang dibutuhkan system, misalnya untuk Google maps, dan lain-lain.
e.
yang
mengimplementasikan activity. Icon dan label menunjuk pada source file yang berisi ikon dan
label yang dapat ditampilkan untuk mewakili activity. Komponen yang lain dideklarasikan
dengan cara yang sama, contohnya elemen <service> untuk service, elemen <receiver> untuk
broadcast receiver, dan elemen <provider> untuk content provider. Activity, service dan
content provider yang dideklarasikan di dalam manifest tidak dapat dilihat oleh sistem, sehingga
tidak dijalankan. Namun, broadcast receiver dapat dideklarasikan baik dalam manifest maupun
dibuat secara dinamis dengan menggunakan kode (sebagai obyek BroadcastReceiver) dan
akan diregistrasikan di dalam sistem dengan memanggil Context.registerReceiver().
Dasar Pemrograman Android
Page 82
perangkat
(seperti
bahasa
yang
berbeda
dan
ukuran
layar).
Untuk setiap sumber daya yang dimasukkan dalam proyek Android, SDK membangun
alat mendefinisikan ID integer unik, yang dapat digunakan untuk referensi sumber daya dari
kode aplikasi atau dari sumber lain yang akan didefinisikan dalam XML. Sebagai contoh, jika
aplikasi berisi file gambar bernama logo.png (disimpan dalam direktori res/drawable/), SDK
menghasilkan sumber daya ID bernama R.drawable.logo, yang dapat digunakan untuk referensi
gambar dan dimasukkan kedalam tampilan Layout aplikasi yang dibuat.
>
<intent-filter . . . >
<action android:name="android.intent.action.MAIN" />
Page 83
Page 84
a. Sebuah
objek
Intent
dilewatkan
Activity.startActivityForResult()
Context.startActivity()
ke
atau
yang ada untuk melakukan sesuatu yang baru. (Ini juga dapat dikirimkan ke
Activity.setResult()
startActivityForResult()).
Intent
diteruskan
Context.sendBroadcast(),
ke
salah
satu
metode
broadcast
Context.sendOrderedBroadcast(),
Context.sendStickyBroadcast()) dikirim
(seperti
atau
Intents object
Sebuah objek Intent adalah bundle of information. Berisi informasi yang menarik bagi
komponen yang menerima intent (seperti tindakan yang akan diambil dan data untuk bertindak
atas) ditambah informasi yang menarik bagi sistem Android (seperti kategori komponen yang
Page 85
harus menangani maksud dan instruksi bagaimana untuk memulai aktivitas target). Pada
prinsipnya, dapat memuat:
Component Name
Nama dari komponen yang harus menangani tujuannya. Bidang ini adalah objek
ComponentName - kombinasi dari nama kelas yang memenuhi syarat dari komponen sasaran
(misalnya "com.example.project.app.FreneticActivity") dan nama paket atur di file manifest dari
aplikasi dimana komponen tersebut berada (misalnya, "com.example.project"). Bagian paket
nama komponen dan nama paket yang ditetapkan dalam manifest tidak harus sama.
Nama komponen opsional. Jika sudah diatur, objek Intent dikirimkan ke sebuah instance
dari kelas yang ditunjuk. Jika tidak diatur, Android menggunakan informasi lainnya di objek
Intent untuk menemukan target yang cocok - lihat Resolusi Intent, nanti dalam dokumen ini.
Nama komponen ditentukan oleh setComponent(), setClass(), atau setClassName() dan
dibaca oleh getComponent().
Action
Sebuah string penamaan action yang akan dilakukan - atau, dalam kasus broadcast intents,
action yang terjadi dan sedang dilaporkan. Kelas Intent mendefinisikan beberapa konstanta
tindakan, termasuk ini:
Constant
ACTION_CALL
ACTION_EDIT
Activity
activity
ACTION_MAIN
activity
ACTION_SYNC
activity
ACTION_BATTERY_LOW
ACTION_HEADSET_PLUG
broadcast receiver
broadcast receiver
ACTION_SCREEN_ON
ACTION_TIMEZONE_CHANGED
broadcast receiver
broadcast receiver
Page 86
Lihat deskripsi Intent kelas untuk daftar lengkap kategori method addCategory() untuk
menempatkan kategori dalam suatu objek Intent, removeCategory() untuk menghapus sebuah
kategori sebelumnya ditambahkan, dan getCategories() untuk mendapat himpunan semua
kategori sedang dalam objek.
Data
URL dari data yang akan bertindak dan jenis MIME dari data tersebut. Tindakan yang
berbeda dipasangkan dengan berbagai jenis spesifikasi data. Sebagai contoh, jika field tindakan
adalah ACTION_EDIT, field data akan berisi URL dari dokumen yang akan ditampilkan untuk
mengedit. Jika ACTION_CALL, bidang data akan mengirim URL dengan nomor yang akan
dipanggil. Demikian pula, jika tindakan itu ACTION_VIEW dan field data merupakan http:URL,
aktivitas penerima akan diminta untuk men-download dan menampilkan data apa pun mengacu
pada URL. Ketika melakukan pencocokan Intent untuk komponen yang mampu menangani data,
sering kali penting untuk mengetahui jenis data (tipe MIME-nya) selain URL-nya. Misalnya,
komponen dapat menampilkan data gambar tidak boleh diminta untuk memutar file audio.
Dalam banyak kasus, jenis data dapat disimpulkan dari URL - khususnya konten: URL,
yang mengindikasikan bahwa data terletak pada perangkat dan dikontrol oleh content provider
(lihat diskusi terpisah pada content provider). Tapi jenis ini juga dapat secara eksplisit diatur
dalam objek Intent. Method setData() menentukan data hanya sebagai sebuah URL, setType()
menetapkan hanya sebagai tipe MIME, dan setDataAndType() menetapkan itu baik sebagai
sebuah URL dan jenis MIME. URL dibaca oleh getData() dan jenis oleh getType().
Category
Sebuah string yang berisi informasi tambahan tentang jenis komponen yang harus
menangani tujuannya. Setiap jumlah deskripsi kategori dapat ditempatkan dalam suatu objek
Intent. Seperti halnya untuk tindakan, kelas Intent mendefinisikan konstanta kategori, termasuk
ini:
Constant
Meaning
Page 87
CATEGORY_BROWSABLE
CATEGORY_GADGET
CATEGORY_HOME
Activity ini menampilkan layar awal, layar pertama pengguna melihat bila
perangkat diaktifkan atau ketika tombol HOME ditekan.
CATEGORY_LAUNCHER
Activity ini dapat menjadi activity awal sebuah tugas dan terdaftar dalam
peluncur aplikasi top level.
CATEGORY_PREFERENCE
Extras
Pasangan key-value untuk informasi tambahan yang harus dikirim ke komponen
penanganan Intent. Sama seperti beberapa tindakan dipasangkan dengan jenis tertentu dari data
URL,
beberapa
dipasangkan
ACTION_TIMEZONE_CHANGED
dengan
tambahan
tertentu.
Misalnya,
Intent
get()
objek Bundle. Bahkan, tambahan dapat diinstal dan dibaca sebagai Bundle menggunakan method
putExtras() dan getExtras().
Flags
Flags berbagai jenis. Banyak menginstruksikan sistem Android bagaimana untuk memulai
suatu kegiatan (misalnya, yang tugas activity ini harus dimiliki) dan cara memanfaatkannya
setelah itu diluncurkan (misalnya, apakah itu termasuk dalam daftar kegiatan baru). Flags
didefinisikan dalam kelas Intent.
Page 88
Intents resolution
Intent dapat dibagi menjadi dua kelompok:
a. Intent eksplisit menunjuk komponen target dengan nama (kolom nama komponen, sebutkan
sebelumnya, memiliki seperangkat nilai). Karena nama komponen umumnya akan tidak
diketahui pengembang aplikasi lain, intent eksplisit biasanya digunakan untuk aplikasi
internal pesan - seperti suatu activity memulai services bawahan atau meluncurkan sister
activity.
b. Intent implisit tidak menyebutkan target (field untuk nama komponen adalah kosong). Intent
implisit yang sering digunakan untuk mengaktifkan komponen dalam aplikasi lain.
Android memberikan sebuah intent eksplisit untuk sebuah instance dari kelas target yang
ditunjuk. Tidak ada dalam objek Intent selain hal-hal komponen nama untuk menentukan
komponen harus mendapatkan Intent.
Sebuah strategi yang berbeda diperlukan untuk intent implisit. Dengan tidak adanya target
yang ditunjuk, sistem Android harus menemukan komponen terbaik (atau komponen) untuk
menangani intent - activity atau services untuk melakukan activity yang diminta atau seperangkat
broadcast receivers untuk menanggapi pengumuman broadcast. Ia melakukannya dengan
membandingkan isi dari objek Intent untuk Intent filter, struktur yang terkait dengan komponen
yang berpotensi dapat menerima Intents. Filter menyampaikan kemampuan komponen dan
membatasi penanganan Intents. Membuka komponen untuk kemungkinan menerima Intents
implisit dari jenis yang disampaikan. Jika komponen tidak memiliki filter intent, maka hanya
dapat menerima Intents eksplisit. Sebuah komponen dengan filter dapat menerima baik Intents
eksplisit dan implisit.
Hanya tiga aspek dari suatu obyek Intent dikonsultasikan ketika objek diuji terhadap Intent
Filter:
a. Action
b. Data (kedua jenis URL dan tipe data)
c. Category
Page 89
Ekstra dan Flags tidak berperan dalam mengatasi komponen yang menerima sebuah
intent.
Intent Filters
Untuk menginformasikan sistem yang Intent Implisiat yang dapat menangani, activity,
services, dan broadcast dapat memiliki satu atau lebih Intent Filter. Setiap filter menggambarkan
kemampuan komponen, bahwa satu set Intent komponen bersedia menerima. Ini untuk Intents
Filter dari tipe yang diinginkan, sementara untuk menyaring Intent yang tidak diinginkan - Intent
implisit yang tidak diinginkan (yang tidak memberi nama kelas target). Intent eksplisit selalu
dikirim ke target, tidak peduli apa yang dikandungnya, filter tidak dikonsultasikan. Tapi intent
implisit disampaikan ke komponen hanya jika dapat melewati salah satu filter komponen itu.
Sebuah komponen memiliki filter yang terpisah untuk setiap pekerjaan yang dapat
dilakukan, setiap tampilan bisa menyajikan kepada pengguna. Misalnya, activity NoteEditor,
contoh dari aplikasi NotePad memiliki dua filter - satu untuk memulai dengan catatan khusus
bahwa pengguna dapat melihat atau mengedit, dan satu lagi untuk mulai dengan catatan kosong
dimana user bisa mengisi dan menyimpan. (Semua filter NotePad yang dijelaskan di bagian
Contoh NotePad, kemudian)
Intent Filter adalah turunan dari kelas IntentFilter. Namun, karena sistem Android harus
mengetahui tentang kemampuan dari komponen sebelum dapat memulai komponen tersebut,
filter intent umumnya tidak diatur dalam kode Java, tetapi dalam file manifest aplikasi
(AndroidManifest.xml) sebagai elemen <intent-filter> . (Satu pengecualian akan menjadi
filter
untuk
broadcast
yang
Context.registerReceiver(),
terdaftar
secara
dinamis
dengan
menghubungi
Filter memiliki kolom yang paralel, data, dan bidang kategori objek Intent. Intent implisit
diuji terhadap filter di ketiga wilayah. Untuk disampaikan kepada komponen yang memiliki
filter, harus lulus semua tiga tes. Jika gagal bahkan salah satu dari mereka, sistem Android tidak
akan mengirimkannya ke komponen - setidaknya tidak berdasarkan filter yang. Namun, karena
komponen dapat memiliki filter intent ganda, intent yang tidak lulus melalui satu filter sebuah
komponen mungkin membuatnya melalui yang lain.
Masing-masing dari tiga tes dijelaskan secara rinci di bawah ini:
Dasar Pemrograman Android
Page 90
1. Action Test
Sebuah elemen <intent-filter> dalam file manifest daftar tindakan sebagai subelements
<action>.
Sebagai contoh:
<intent-filter . . . >
<action android:name="com.example.project.SHOW_CURRENT" />
<action android:name="com.example.project.SHOW_RECENT" />
<action android:name="com.example.project.SHOW_PENDING" />
. . .
</intent-filter>
Sebagai contoh adalah menampilkan, sedangkan obyek Intent menamai hanya satu
tindakan, filter dapat berisi lebih dari satu. Daftar ini tidak boleh kosong filter harus mengandung
setidaknya satu unsur <action>, atau akan memblokir semua Intent. Untuk lulus tes ini,
tindakan yang ditentukan dalam objek Intent harus sesuai dengan salah satu tindakan yang
tercantum dalam filter. Jika objek atau filter tidak menentukan tindakan, hasilnya adalah sebagai
berikut:
Jika filter gagal untuk membuat daftar activity, tidak ada intent untuk untuk menyesuaikan,
sehingga semua intent gagal tes. Tidak ada intens yang bisa melewati filter. Di sisi lain, objek
Intent yang tidak menentukan suatu activity otomatis lulus uji - selama filter berisi setidaknya
satu activity.
2. Category Test
Sebuah elemen <intent-filter> juga daftar kategori sebagai subelements. Sebagai
contoh:
<intent-filter . . . >
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
. . .
</intent-filter>
Perhatikan bahwa konstanta dijelaskan sebelumnya atas tindakan dan kategori tidak
digunakan dalam file manifest. Nilai string penuh digunakan sebagai gantinya. Misalnya,
Dasar Pemrograman Android
Page 91
di
intent
filter
mereka.
(Filter
dengan
Setiap elemen <data> dapat menentukan URL dan jenis data (tipe MIME media). Ada
atribut yang terpisah - skema, host, port, dan path - untuk setiap bagian dari URL:
scheme://host:port/path
Page 92
Skema itu "content", host adalah "com.example.project", port "200", dan pathnya adalah
"folder / subfolder / etc". Host dan port bersama-sama merupakan otoritas URL, jika sebuah host
yang tidak ditentukan, port diabaikan. Masing-masing atribut adalah opsional, tetapi mereka
tidak independen satu sama lain: Untuk otoritas menjadi berarti, skema juga harus ditetapkan.
Untuk jalan menjadi berarti, baik skema dan kewenangan harus ditentukan.
Ketika URL dalam suatu objek Intent dibandingkan dengan spesifikasi URL di filter, itu
dibandingkan hanya pada bagian-bagian dari URL sebenarnya yang disebutkan dalam filter.
Misalnya, jika filter hanya menentukan skema, semua URL dengan skema yang cocok dengan
filter. Jika filter menentukan skema dan otoritas tetapi tidak ada path, semua URL dengan skema
yang sama dan otoritas pertandingan, terlepas dari jalur mereka. Jika filter menentukan skema,
otoritas, dan path, hanya URL dengan skema yang sama, otoritas, dan pertandingan path.
Namun, spesifikasi path dalam filter dapat berisi wildcard untuk hanya memerlukan
pertandingan parsial jalan.
Jenis atribut dari elemen <data> menetapkan tipe MIME dari data. Ini lebih sering terjadi
pada filter dari URL. Kedua objek Intent dan filter dapat menggunakan wildcard "*" untuk field
subtype - misalnya, "text / *" atau "audio / *" - yang menunjukkan setiap pertandingan subtype.
Tes data yang membandingkan kedua URL dan tipe data dalam objek Intent untuk jenis URL
dan data yang ditetapkan dalam filter. Aturannya adalah sebagai berikut:
1. Sebuah objek Intent yang berisi bukan sebuah URL atau tipe data lulus uji hanya jika filter
juga tidak menjelaskan jenis URL atau data.
2. Sebuah objek Intent yang berisi URL tetapi tidak ada tipe data (dan jenis yang tidak dapat
disimpulkan dari URL) melewati tes hanya jika URL cocok URL dalam filter dan filter juga
tidak menentukan tipe. Ini akan menjadi kasus hanya untuk URL seperti mailto: dan tel:
bahwa tidak mengacu pada data aktual.
3. Sebuah objek Intent yang berisi tipe data tetapi tidak URL lulus uji hanya jika filter berisi
daftar tipe data yang sama dan juga tidak menentukan URL.
4. Sebuah objek Intent yang berisi URL dan tipe data (atau tipe data dapat disimpulkan dari
URL) melewati bagian data jenis tes hanya jika jenisnya cocok dengan jenis yang tercantum
dalam saringan. Melewati bagian URL dari tes baik jika URL cocok URL dalam filter atau
jika memiliki konten: atau file: URL dan filter tidak menentukan URL. Dengan kata lain,
Dasar Pemrograman Android
Page 93
komponen dianggap mendukung konten: dan file: data jika daftar penyaring yang hanya tipe
data. Jika intent itu dapat melewati filter lebih dari satu activity atau services, pengguna
mungkin akan diminta yang komponen untuk mengaktifkan. Exception dimunculkan jika
target tidak dapat ditemukan.
pengguna menyentuh BACK key, maka activity sebelumnya akan tampil di layar.
Pengguna akan berfikir bahwa map viewer tersebut ada di dalam aplikasi yang sama
sebagai activity, walaupun pada kenyataannya tidak. Map viewer didefinisikan di dalam aplikasi
yang lain yang berjalan di dalam proses aplikasi tersebut. Android menjaga user experience ini
dengan cara menjalankan dua activity di dalam task yang sama. Task merupakan sekumpulan
activity yang saling terhubung dan diatur dalam sebuah stack. Activity yang ada di posisi paling
bawah adalah activity yang memulai task, pada umumnya activity ini yang dipilih pengguna
pada application launcher. Sedangkan activity yang terletak paling atas adalah activity yang
sedang berjalan atau activity yang berfokus pada aksi dari pengguna. Ketika sebuah activity
memicu activity lainnya, maka activity baru akan masuk ke dalam susunan dan menjadi activity
yang aktif. Activity sebelumnya akan tetap berada di dalam stack dan ketika pengguna
menyentuh tombol BACK, activity tersebut akan dikeluarkan dari dalam stack sehingga activity
sebelumnya akan aktif kembali.
Susunan tersebut mempunyai object, sehingga apabila sebuah task terdiri dari satu instance
dari subclass activity yang sama, contohnya map viewer lebih dari satu- maka susunan tersebut
mempunyai entry yang terpisah untuk setiap instance. Activity di dalam susunan tersebut tidak
pernah tersusun ulang, hanya keluar dan masuk.
Page 94
Task merupakan susunan dari activity-activity, bukan sebuah class atau elemen di dalam file
manifest. Sehingga tidak ada cara untuk menentukan nilai dari task yang tidak tergantung pada
activity-nya. Nilai dari beberapa task sebagai suatu kesatuan ditentukan di dalam activity yang
terletak pada sususan dasar. Contohnya, bagian berikutnya akan berisi tentang afinitas task;
bahwa nilainya diketahui dari rangkaian persamaan task activity yang terletak pada stack paling
dasar.
Semua activity di dalam task bergerak bersama sebagai sebuah unit. Task keseluruhan
dapat dibawa ke atas permukaan atau dikirim ke layar. Contohnya, task pada saat ini mempunyai
empat activity di dalam susunannya, maka terdapat tiga activity yang terletak di bawah activity
yang sedang berjalan. Kemudian pengguna menyentuh kunci HOME, maka tampilan akan
berpindah ke application launcher, dan memilih sebuah aplikasi. Maka task pada saat itu akan
ditempatkan sebagai latar dan activity dasar akan ditampilkan. Dalam waktu singkat, pengguna
akan melihat tampilan kembali ke home dan memilih aplikasi yang sebelumnya (task yang
sebelumnya). Task itu, dengan keempat activity di dalamnya, dibawa ke permukaan. Ketika
pengguna menyentuh back key, tidak akan ditampilkan activity yang baru saja ditinggalkan oleh
pengguna (activity dasar pada task sebelumnya), melainkan activity yang ada pada susunan
paling atas akan dilepas dan menampilkan activity sebelumnya yang ada di dalam task yang
sama.
Perilaku di atas adalah perilaku default dari activity dan task. Namun ada beberapa cara
untuk memodifikasi semua aspek tersebut. Hubungan antara activity dan task, dan perilaku
activity di dalam task, dikendalikan oleh interaksi antara aturan flag yang diatur di dalam intent
object, yang memulai activity dan atribut yang terdapat di dalam elemen <activity> di dalam
manifest. Sehingga pengirim permintaan dan pemberi respon akan mempunyai informasi yang
sama. Dalam hal ini, intent flag yang pokok adalah:
a. FLAG_ACTIVITY_NEW_TASK
b. FLAG_ACTIVITY_CLEAR_TOP
c. FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
d. FLAG_ACTIVITY_SINGLE_TOP
Atribut pokok <activity> adalah:
a. taskAffinity
Page 95
b. launchMode
c. allowTaskReparenting
d. clearTaskOnLaunch
e. alwaysRetainTaskState
f. finishOnTaskLaunch
Bagian berikutnya akan menggambarkan fungsi dari flag dan atribut di atas, bagaimana
interaksinya dan atas pertimbangan apakah menggunakan flag tersebut.
mempunyai
FLAG_ACTIVITY_NEW_TASK
flag
allowTaskReparentingactivity
dan
ketika
atribut
a. Flag FLAG_ACTIVITY_NEW_TASK
Sebagaimana telah disebutkan sebelumnya, secara default, newactivity ketika diluncurkan ke
dalam task menggunakan kode startActivity() maka activity tersebut akan dimasukkan ke
dalam susunan yang sama dengan activity yang memanggilnya. Tetapi jika intent object
startActivity()
maka sistem akan mencari task yang berbeda untuk menempatkan activity yang baru tersebut.
Ketika flag baru tersebut diimplementasikan, maka dibuatlah sebuah task baru. Namun jika telah
ada task yang mempunyai afinitas yang sama dengan activity yang baru, maka activity baru akan
diluncurkan di dalam task tersebut.
b. Atribut allowTaskReparenting
Jika sebuah activity mempunyai atribut allowTaskReparenting yang dinyatakan true,
maka activity tersebut dapat berpindah dari task-nya dan masuk ke dalam task yang memiliki
afinitas ketika task tersebut muncul. Contohnya, ketika ada sebuah activity yang melaporkan
Dasar Pemrograman Android
Page 96
kondisi cuaca pada kota tertentu dinyatakan sebagai bagian dari sebuah aplikasi pariwisata.
Activity tersebut memiliki afinitas yang sama dengan activity lain di dalam aplikasi yang sama
(afinitas default) maka pada saat itu diizinkan untuk reparenting.
Satu activity memicu laporan cuaca, sehingga activity tersebut memiliki task yang sama.
Kemudian aplikasi pariwisata muncul, dan activity laporan cuaca akan ditugaskan kembali dan
ditampilkan bersama dengan task tersebut. Jika sebuah file .apk mempunyai lebih dari satu
aplikasi dari sisi pengguna, lebih baik menugaskan afinitas yang berbeda ke activity yang
berbeda yang masing-masing terhubung satu sama lain.
3.4.8 LaunchMode
Terdapat empat launch mode berbeda yang bisa ditugaskan pada sebuah elemen
<activity>
a. standard(mode default)
b. singleTop
c. singleTask
d. singleInstance
Mode di atas berbeda dari empat faktor berikut ini:
1. Task apa yang mempunyaiactivity yang akan merespon intent?
Bagi mode standard dan singleTop, task yang berasal dari intent (dan dipanggil
startActivity()
Dalam hal ini, akan dipilih task yang berbeda sebagaimana telah dijelaskan pada bagian
sebelumnya. Mode singleTask dan singleInstance akan menandai activity yang selalu
ada di posisi dasar pada task. Mereka memilih sebuah task, dan tidak pernah dimasukkan pada
task yang lainnya.
2. Adakah multipleinstance di dalam activity?
Bagi mode standard dan singleTop dapat diinstansikan beberapa kali. Mereka bisa
terdapat dalam beberapa task, dan di dalam task tersebut dapat mempunyai multiple instance
pada activity yang sama. Pada mode singleTask dan singleInstance, activity dibatasi
Dasar Pemrograman Android
Page 97
pada satu instance. Karena activity ini terletak di dasar task, maka batasan ini berarti bahwa tidak
ada lebih dari satu instance di dalam task di perangkat tersebut pada saat yang bersamaan.
3. Apakah instance mempunyai activity yang berbeda di dalam task-nya?
Activity singleInstance berdiri sendiri sebagai satu satunya activity di dalam sebuah task.
Jika memicu activity yang lain, maka activity tersebut akan diluncurkan ke dalam task yang lain
tanpa memperhatikan mode peluncurannya, sebagaimana jika flag FLAG_ACTIVITY_NEW_TASK
ada di dalamintent. Pada beberapa hal, mode singleInstance mirip dengan mode singleTask.
Tiga mode yang lain mengizinkan multiple activity di dalam satu task. Activity singleTask
akan selalu menjadi activity dasar di dalam task, namun dapat memicu activity lain yang akan
ditugaskan dalam task tersebut. Instance dari activity standard dan singleTop dapat
muncul di bagian manapun dalam susunan task.
4. Apakah instance baru dari kelas akan diluncurkan untuk menangangi intent baru?
Pada mode standard secara default, instance baru akan dibuat untuk merespon setiap intent
baru yang muncul. Setiap instance akan menangani satu intent saja. Untuk mode singleTop,
setiap instance yang ada di dalam kelas akan digunakan kembali untuk menangani intent baru
jika activity tersebut ada pada posisi atas di dalam susunan task. Jika tidak terdapat pada posisi
atas, maka instance tersebut tidak akan digunakan kembali, dan akan dibuat sebuah intance baru
untuk intent baru dan memasukkannya ke dalam susunan.
Misalnya, di dalam sebuah susunan task activity terdapat activity dasar A, kemudian activity B, C
dan D di atasnya. Maka susunannya akan berpola A-B-C-D. Sebuah intent tiba untuk activity D,
jika D mempunyai mode standard, maka instance baru akan diluncurkan dan susunannya
akan berpola A-B-C-D-D. Namun, jika activity D menggunakan mode singleTop, maka
instance yang ada diandalkan untuk menangani intent yang baru (karena D ada di posisi paling
atas), dan pola susunannya tetap A-B-C-D.
Jika intent yang tiba ditujukan untuk activity B, maka instance yang baru untuk B akan tetap
diluncurkan, tanpa memperhatikan apakah B menggunakan mode standard atau
singleTop
(karena B tidak berada pada posisi atas), maka pola susunannya adalah A-B-C-D-
B.
Dasar Pemrograman Android
Page 98
Sebagaimana disebutkan di atas, tidak akan ada lebih dari satu instance bagi activity mode
singleTask
semua intent baru yang muncul. Activity yang menggunakan mode singleInstance akan
selalu ditempatkan pada posisi atas (karena satu satunya activity di dalam task) maka akan selalu
menempati posisi untuk menangani intent. Namun activity singleTask dapat mempunyai atau
tidak mempunyai activity lain di atasnya. Jika ada activity lain, maka activity ini tidak pada
posisi untuk menangani intent. Dan intent akan dihapus. (Walaupun intent ini dibuang,
kedatangannya tetap akan menyebabkan task dimunculkan dan tetap ada di permukaan).
Ketika activity yang ada diminta untuk menangani intent baru, intent object akan dilewatkan ke
activity dengan memanggil onNewIntent(). (intent object yang diawali oleh activity akan
diambil dengan memanggil getIntent()). Ingatlah bahwa ketika sebuah instanceactivity dibuat
untuk menangani sebuah intent, pengguna dapat menyentuh tombol back untuk kembali ke
keadaan layar sebelumnya (activity sebelumnya). Namun jika instance yang sudah ada
menangani intent baru, maka pengguna tidak dapat menyentuh tombol back untuk kembali ke
keadaan sebelum intent datang.
3.4.9 Membersihkan Stack
Jika pengguna meninggalkan task untuk waktu yang lama, sistem akanmembersihkan task
semua activity kecuali activitydasar. Ketika pengguna kembali ke task lagi, maka pengguna akan
melihat tampilan sebagaimana ketika pengguna meninggalkannya, kecuali bila activity awal
dijalankan.Setelah beberapa saat, pengguna akan meninggalkan apa yang sedang dilakukan
sebelumnya dan kembali ke task untuk memulai activity yang lain.
Secara umum,ada beberapa atribut activity yang dapat digunakan untuk mengendalikan
perilaku ini dan memodifikasinya:
a. Atribut alwaysRetainTaskState - Jika atribut ini dinyatakan true pada activity dasar di
sebuah task, maka perilaku default yang baru saja dijabarkan tidak akan terjadi. Karena task
akan menahan semua activity untuk tetap berada di dalam susunan meskipun dalam jangka
waktu yang lama
b. Atribut clearTaskOnLaunch - Jika atribut ini dinyatakan true pada activity dasar di
sebuah task, maka susunan akan dibersihkan hingga ke dasar, kapanpun pengguna
Dasar Pemrograman Android
Page 99
meninggalkan
task
hingga
kembali.
Dengan
kata
lain,
berlawanan
dengan
alwaysRetainTaskState, dimana pengguna akan selalu kembali kepada kondisi ketika task
ditinggalkan.
c. Atribut finishOnTaskLaunch- Atribut ini mirip dengan clearTaskOnLaunch, namun
beroperasi hanya pada activity tunggal, tidak pada keseluruhan task. Atribut ini juga dapat
menyebabkan activity lain keluar dari susunan, termasuk activity dasar. Ketika nilainya
dinyatakan true, maka activity yang tersisa adalah sebagian activity yang tersisa di dalam
task pada saat itu. Apabila pengguna meninggalkannya dan kembali kepada task tersebut,
maka task itu telah hilang.
Ada cara lain untuk membuat activity dibersihkan dari susunan. Jika intent object termasuk
ke dalam flag FLAG_ACTIVITY_CLEAR_TOP , dan tujuan task mempunyai instance dari
jenisactivity yang harus menangani intent di dalam susunan, maka semua activity di atas semua
instance akan dibersihkan sehingga instance akan tetap ada di atas susunan dan merespon intent.
Jika mode peluncuran activity tersebut adalah standard, maka activity itu tetap dibersihkan
dari susunan, dan instance baru akan diluncurkan untuk menangani instance yang datang. Hal ini
dikarenakan instance yang baru selalu dibuat untuk intent baru ketika mode peluncuran activity
adalah standard.
Flag yang paling banyak digunakan adalah FLAG_ACTIVITY_CLEAR_TOP yang akan
terhubung dengan FLAG_ACTIVITY_NEW_TASK. Ketika digunakan bersama, kedua flag ini akan
menempatkan activity yang ada di task yang lain dan menempatkannya pada posisi agar dapat
merespon intent.
filter
android.intent.action.MAIN
android.intent.category.LAUNCHER
yang
ditentukan
sebagai
aksi
dan
dan label acvitivity di application launcher, memberikan akses kepada pengguna untuk
meluncurkan task dan kembali ke applicaion launcher kapan saja pengguna menginginkannya.
Kemampuan yang kedua ini sangatlah penting: pengguna harus dapat meninggalkan task
dan dapat kembali lagi nantinya. Dalam hal ini, dua mode peluncuran yang menandai activity
Dasar Pemrograman Android
Page 100
untuk memulai task; singleTask dan singleInstance harus digunakan hanya ketika
activity mempunyai filter MAIN dan LAUNCHER. Coba bayangkan, apa yang akan terjadi
apabila filter tersebut hilang?. Sebuah intent akan meluncurkan activity mode singleTask,
memulai sebuah task baru, dan pengguna akan membutuhkan waktu lebih lama untuk bekerja
pada task tersebut. Kemudian, pengguna akan menyentuh tombol home. Berikutnya task akan
diperintahkan untuk bekerja di latar dan hilang dari layar home. Dan karena tidak
direpresentasikan di dalam application launcher, pengguna tidak dapat kembali ke task tersebut.
Flag FLAG_ACTIVITY_NEW_TASK juga mengalami masalah yang sama. Jika flag ini
menyebabkan activity untuk memulai task baru dan pengguna menekan tombol home untuk
meninggalkannya, maka harus ada navigasi lain untuk memberikan akses kembali. Sejumlah
entitas (seperti notification manager) selalu memulai activity pada task eksternal, bukan di dalam
bagiannya, maka entitas tersebut selalu meletakkan flag FLAG_ACTIVITY_NEW_TASK di dalam
intent yang dilewatkan ke startActivity(). Jika terdapat activity yang dapat diminta oleh
entitas eksternal yang mungkin menggunakan flag ini, maka berhati hatilah dengan memberikan
cara pada pengguna untuk kembali ke task yang dimulai sebelumnya. Pada kasus jika tidak ingin
pengguna dapat kembali ke activity sebelumnya, tentukan nilai pada finishOnTaskLaunchdi
elemen <activity> menjadi true.
3.5
3.5.1 Proses
Proses adalah sesuatu dimana sebuah komponenberjalan dikendalikan oleh file manifest.
Elemenkomponen <activity>, <service>, <receiver>, dan <provider> mempunyai
atribut process yang akan menentukan sebuah proses dimana komponen akan berjalan. Atribut
ini dapat diatur sehingga setiap komponen akan berjalan pada prosesnya masing-masing, atau
beberapa komponen akan berbagi sebuah proses sementara dan yang lainnya tidak. Komponen
tersebut juga dapat diatur sehingga aplikasi yang berbeda dapat berjalan pada proses yang sama,
sebagaimana dilakukan pada Linux, yaitu aplikasi dapat digunakan oleh ID pengguna dan izin
akses yang sama. Elemen <application> juga mempunyai atribut process untuk mengatur nilai
default yang akan diaplikasikan pada semua komponen.
Page 101
Semua komponen akan diinstansi pada thread utama pada proses yang telah ditentukan,
dan sistem memanggil komponen yang dikirim dari thread tersebut. Setiap instance tidak akan
dibuatkan thread yang terpisah. Sehingga method yang merespon pemanggilan tersebut seperti
View.onKeyDown()
yang akan melaporkan aksi pengguna dan notifikasi siklus hidup yang akan
dibahas nanti pada bagian Siklus Hidup Komponen akan selalu berjalan pada thread utama di
dalam proses. Artinya tidak ada komponen yang akan berjalan pada waktu lama atau memblokir
operasi (seperti operasi jaringan atau komputasi loop) ketika dipanggil oleh sistem, karena hal ini
akan memblokir komponen lain yang ada di dalam proses. Untuk menanganinya, buatlah thread
untuk operasi yang membutuhkan waktu lama.
Android dapat mematikan sebuah proses pada saat tertentu, ketika kondisi memori rendah
dan ada proses lain harus melayani pengguna dengan segera. Komponen aplikasi yang berjalan
di proses akan dimatikan pada saat itu. Sebuah proses akan dijalankan kembali proses tersebut
dibutuhkan oleh aplikasi. Ketika sebuah proses dimatikan, Android akan mempertimbangkan
kepentingannya terhadap pengguna. Contohnya, jika ada dua proses activity,yang tampil dan
tidak tampil di layar, maka android akan mematikan proses yang tidak sedang tampil di layar.
Keputusan untuk mematikan proses itu sendiri tergantung pada komponen yang berjalan pada
proses tersebut.
3.5.2 Thread
Jika ingin membatasi aplikasi menjadi proses tunggal, maka akan ada saat dimana harus
membuat sebuah thread untuk melakukan pekerjaan pada layar. Karena interface harus dapat
memberikan respon cepat kepada pengguna, maka thread yang bertanggung jawab terhadap
sebuah activity tidak boleh memakan waktu lama seperti mengunduh file dari jaringan. Proses
yang membutuhkan waktu lama harus dibuatkan sebuah thread baru.
Thread dibuat dengan menggunakan bahasa standar Java menjadi object Thread. Android
menyediakan beberapa class yang dapat digunakan untuk mengatur thread, yaitu Looper untuk
menjalankan pesan yang berkesinambungan (looping message), Handler untuk memproses
pesan, dan HandlerThread untuk mengatur thread dengan pesan berkesinambungan.
Page 102
pemanggilan
IPC.
Lalu
membuat
turunan
(subclass)
Stub
untuk
Page 103
interface yang dihasilkan oleh tool tersebut. Berikut ini adalah cara kerja koneksi service dan
client:
a. Client
lokal
akan
mengimplementasikan
onServiceDisconnected()
method
onServiceConnected()
dan
service remote. Dan ketika koneksi tersebut selesai, dapat memanggil method
bindService()
b. Method onBind() dari service dapat diimplementasikan, baik untuk menerima atau menolak
koneksi, tergantung dari intent yang diterima (intent akan dilewatkan ke bindService()).
Jika koneksi diterima, maka akan mengembalikan instance dari turunan Stub.
c. Jika
service
menerima
onServiceConnected()
koneksi,
maka
Android
akan
memanggil
method
turunan Stub akan diatur oleh service. Melalui proxy, client akan melakukan panggilan ke
service remote.
akan dipanggil dari thread yang ada pada kumpulan thread. Mengingat thread
dapatmempunyai lebih dari satu client, maka ada lebih dari satu kumpulan thread yang dapat
menggunakan method IBinder yang sama pada saat yang sama. Method IBinder harus
diimplementasikan ke dalam thread-safe.
Page 104
Content provider dapat menerima permintaan data dari proses yang lain. Walaupun kelas
ContentResolver dan ContentProvider menyembunyikan detil komunikasi interproses. Method
ContentProvider
yang
merespon
permintaan
tersebut
adalah
method
thread dari proses ContentProvider, bukan dari thread utama di dalam proses. Karena methodmethod ini dapat dipanggil dari sejumlah thread manapun pada saat yang sama, maka harus
diimplementasikan secara thread-safe.
3.6
Setiap perubahan status activity akan mengeluarkan notifikasi yang dapat dilakukan
dengan cara memanggil protected method berikut ini:
a. void onCreate(Bundle savedInstanceState)
b. void onStart()
Dasar Pemrograman Android
Page 105
c. void onRestart()
d. void onResume()
e. void onPause()
f. void onStop()
g. void onDestroy()
Semua method di atas saling terkait dan dapat di-override untuk melakukan pekerjaan yang
sesuai ketika terjadi perubahan status. Semua activity harus mengimplementasi onCreate()
untuk melakukan pengaturan awal ketika object pertama kali diinstansi. Ada beberapa method
yang akan mengimplementasi onPause() untuk menjalankan perubahan data menghentikan
interaksi dengan pengguna. Implementasi dari method siklus hidup activity harus selalu
memanggil versi superclass. Contoh kode yang digunakan seperti berikut ini.
protectedvoid onPause(){
super.onPause();
...
}
Secara keseluruhan, tujuh method di atas mendefinisikan keseluruhan siklus hidup sebuah
activity. Ada beberapa nested loop yang dapat dipantau dengan mengimplementasikan method
tersebut:
a. Entire
Lifetime, masa hidup activity dimulai pada saat method onCreate() dipanggil hingga
method onDestroy() dipanggil. Activity akan memulai aturan pertama pada kondisi global
pada onCreate() dan melepaskan semua resourceyang tersisa ketika onDestroy()
dipanggil. Contohnya, jika ada sebuah thread yang berjalan pada latar untuk mengunduh data
dari jaringan, maka thread tersebut akan dibuat pada onCreate() dan dihentikan pada
onDestroy().
b. Visible Lifetime, ketika activity tampak di layar, terjadi pada saat method onStart()
dipanggil hingga onStop(). Pada masa ini, pengguna dapat melihat activity di layar,
walaupun tidak muncul di permukaan dan berinteraksi dengan pengguna. Di antara kedua
method ini, resource yang dibutuhkan akan tetap aktif untuk menunjukkan activity
kepadapengguna.
Contohnya,
anda
dapat
mendaftarkan
BroadcastReceiver
pada
Page 106
onStart()
melepaskannya pada onStop() ketika anda ingin menghilangkan tampilan activity dari layar.
Method onStart() dan onStop() dapat dipanggil berkali-kali, tergantung pada situasi ketika
activity ingin ditampilkan atau tidak.
c. Foreground Lifetime, masa hidup di permukaan. Terjadi ketika method onResume() dipanggil
hingga method onPause(). Selama periode ini, activity beriteraksi dengan pengguna dan
terletak di atas semua activity yang lain. Sebuah activity dapat bertransisi antara kondisi
resumed dan pause-contohnya, onPause() dipanggil ketika perangkat diatur pada kondisi
sleep atau ketika activity baru dimulai. Dan onResume() dipanggil ketika hasil dari activity
muncul atau ada intent baru yang dikirimkan. Oleh karena itu, kode pada kedua method ini
sangatlah ringan.
Diagram berikut ini akan menggambarkan loop dan path yang dilalui activity ketika
berpindah kondisi. Bentuk oval yang berwarna merupakan kondisi umum activity. Bentuk
persegi panjang menggambarkan pemanggilan method yang dapat anda panggil untuk
melaksanakan operasi ketika activity melakukan transisi kondisi.
Page 107
Tabel berikut ini akan menunjukkan method tersebut secara rinci dan menjelaskan lokasi method
di dalam siklus hidup activity.
Method
onCreate()
Deskripsi
Dipanggil ketika activity pertama dibuat.
Dapat
dihentikan?
Tidak
Selanjutnya
onStart()
Page 108
Tidak
onStart()
Tidak
onResume()
atau
onStop()
Tidak
onPause()
Ya
onResume()
atau
onStop()
Page 109
onResume()
Ya
onRestart()
atau
onDestroy()
Ya
Tidak ada
Perlu diketahui bahwa kolom Dapat Dihentikan di atas menunjukkan apakah sistem
dapat menghentikan proses dari setiap activity pada waktu kapanpun nilai method dikembalikan,
tanpa mengeksekusi baris lain di dalam activity. Tiga method (onPause(), onStop() dan
onDestroy())
maka hanya method itu yang dijamin akan dipanggil sebelum proses dimatikan. Namun tidak
dengan onStop() dan onDestroy(). Oleh karena itu, sebaiknya menggunakan onPause() untuk
menulis data persistence seperti data yang disunting oleh pengguna pada storage.
Dasar Pemrograman Android
Page 110
Method yang dinyatakan Tidak pada kolom Dapat Dihentikan menandakan bahwa
proses tidak dapat mematikan activity sejak dipanggil. Misalnya pada waktuonPause() hingga
kembalionResume() , maka activity tidak dapat dihentikan hingga methodonPause() dipanggil
kembali. Jadi, walaupun secara teknis sebuah activity tidak dapat dihentikan, maka dengan
definisi ini, tetap dapat dimatikan oleh sistem, namun hal itu hanya dapat terjadi pada kondisi
dan situasi tertentu ketika perangkat tidak lagi mempunyai sumber daya yang memadai.
dipanggil, Android akan melewatkan method object Bundle yang dapat menyimpan
kondisi dinamis dari activity sebagai name-value pairs. Ketika activity dijalankan kembali, maka
Bundle
akan
dilewatkan
onRestoreInstanceState()
pada
dua
method,
yaitu
onCreate()
dan
method
atau salah satu dari method tersebut dapat mengembalikan kondisi seperti sedia kala.
Tidak seperti method onPause() dan method yang dijelaskan sebelumnya, method
onSaveInstanceState()
Kedua
method
ini
onSaveInstanceState()
selalu
dipanggil.
Contohnya,
Android
memanggil
sebelum activity dimatikan oleh sistem, namun pada situasi ini masih
Page 111
Ketika sebuah activity memicu activity lainnya, maka kedua activity tersebut akan
mengalami transisi siklus hidup. Ketika salah satunya berubah status menjadi pause atau stop,
maka yang lainnya akan dijalankan. Pada saat tertentu, ada kemungkinan dibutuhkan koordinasi
antara activity ini. Urutan pemanggilan siklus hidup ini telah ditentungkan, khususnya ketika dua
activity berada di dalam proses yang sama:
a. Method onPause() dari activity yang sedang berjalan akan dipanggil.
b. Method onCreate(), onStart() dan onResume() dari activity yang baru saja dijalankan
akan dipanggil.
c. Kemudian jika activity yang baru saja dimulai ingin disembunyikan, maka method
onStop()
Hanya
membutuhkan
satu
kali
panggilan
startService().
Page 112
koneksi dengan service dengan memanggil bindService(). Pada kasus seperti ini,
stopService()
Seperti
activity,
service
juga
mempunyai
method
siklus
hidup
yang
dapat
diimplementasikan untuk memantau perubahan statusnya. Tetapi service hanya mempunyai tiga
public method:
a. voidonCreate()
b. void onStart(Intent intent)
c. void onDestroy().
Dengan mengimplementasikan ketiga method ini, dapat dipantau dua nested loop dari siklus
hidup service, yaitu:
1. Entire Lifetime, masa hidup service adalah pada periode ketika method onCreate()
dipanggil hingga kemudian semua resource dilepaskan dengan memanggil onDestroy().
Serupa dengan activity, service juga menetapkan aturan awal pada pemanggilan onCreate(),
dan melepaskan semua resource pada onDestroy(). Misalnya, service yang memainkan
musik pada background dapat membuat thread ketika musik akan dimainkan di dalam
method onCreate(),dan akan menghentikan thread pada onDestroy().
2. Active Lifetime, masa hidup aktif sebuah service akan dimulai dengan memanggil
onStart().
Method ini akan membuat intent object yang akan dilewatkan di method
startService().
Kemudian musik akan membuka intent untuk menentukan lagu yang akan
Page 113
Pemanggilan balik onBind() ditangani oleh intent object yang dilewatkan ke bindService.
Dan onUnbind() ditangani oleh intent yang dilewatkan di unbindService(). Jika service
mengizinkan koneksi tersebut, maka onBind() akan mengembalikan jalur komunikasi yang
digunakan client untuk berinteraksi dengan service. Method onUnbind() dapat meminta
onRebind()
untuk dipanggil jika ada client baru yang ingin membuka koneksi dengan service
tersebut.
Diagram berikut ini menggambarkan metode pemanggilan balik sebuah service. Walaupun
service yang dibuat melalui startService dengan service yang dibuat oleh bindService()
dipisahkan. Ingatlah bahwa semua service, dapat mengizinkan client untuk menjalin koneksi,
sehingga service apapun dapat menerima panggilan onBind() dan onUnbind().
Page 114
Proses dengan broadcast receiver yang aktif tidak akan dimatikan. Namun, proses dengan
komponen yang tidak aktif dapat dimatikan oleh sistem setiap saat, ketika memori yang
digunakannya sedang dibutuhkan oleh proses lainnya. Hal ini menimbulkan masalah ketika respon
ke broadcast message adalahmemakan waktu dan untuk itu perlu dilakukan sesuatu pada thread
yang terpisah, jauh dari thread utama dimana komponen lain dari interface pengguna sedang
berjalan. Jika onReceive() membuat
sebuah thread
keseluruhan, termasuk thread yang baru dibuat akan dinilai tidak dalam keadaan aktif (kecuali
ada komponen aplikasi lain yang sedang aktif di dalam proses tersebut) dan dapat
dimatikankapan saja. Solusi dari masalah ini adalah mengatur onReceive() untuk memulai
service baru yang akan menangani pekerjaan tersebut, sehingga sistem akan tahu bahwa masih
ada pekerjaan aktif yang masih dilakukan di dalam proses.
Page 115
1. Foreground process, proses yang berjalan di permukaan. Merupakan proses yang ada di
tingkat paling atas, menangani apa yang sedang dilakukan oleh pengguna. Proses yang ada di
permukaan adalah proses dengan kondisi sebagai berikut:
a. Menjalankan activity yang berinteraksi dengan pengguna (method onResume() obyek
activity telah dipanggil ).
b. Menjalankan service yang menangani activity yang berinteraksi dengan pengguna.
c. Mempunyai obyek yang akan mengeksekusi pemanggilan kembali siklus hidupnya
(onCreate(), onStart() atau onDestroy() ).
d. Mempunyai obyek BroadcastReceiver yang akan mengeksekusi method onReceive().
Beberapa Foreground process akan dijalankan pada satu waktu. Proses tersebut akan
dimatikan ketika lowmemory sehingga tidak semua proses dapat dijalankan pada saat yang
bersamaan. Umumnya ketika sampai pada tahap itu, perangkat akan melakukan pembagian
memori (memory paging) yang akan menentukan proses mana yang akan dimatikan dan
menjaga agar antar muka tetap responsif.
2. Visible Process, proses yang dapat terlihat di layar. Proses ini tidak mempunyai komponen
pada foreground, tapi masih dapat mempengaruhi apa yang pengguna lihat di layar. Ciri dari
proses ini adalah sebagai berikut:
a. Menjalankan aktifitas yang tidak tampil di permukaan, namun masih dapat terlihat oleh
penguna (method onPause() telah dipanggil). Hal ini dapat terjadi, misalnya, jika activity
foreground adalah sebuah dialog yang masih memperlihatkan activity di belakangnya.
b. Menjalankan service yang terikat pada activity yang masih dapat terlihat Visible activity
dianggap sebagai activity yang penting dan tidak akan dimatikan kecuali memori sedang
dibutuhkan untuk menjalankan proses yang ada di permukaan.
3. Service process, merupakan proses yang menjalankan service yang telah dimulai dengan
memanggil method startService() dan tidak berpindah ke dua kategori service di atasnya.
Walaupun proses service tidak terikat secara langsung kepada apapun yang dilihat oleh
pengguna. Contohnya memainkan musik MP3 pada latar atau mengunduh data dari jaringan,
sehingga sistem akan tetap menjalankannya selama ada memori yang tersedia dan tidak
mengganggu proses foreground dan visible.
Page 116
4. Background Process, merupakan activity yang dijalankan tanpa terlihat oleh pengguna dan
berjalan pada background (object method onStop() telah dipanggil). Proses ini tidak
berdampak langsung pada experience pengguna, dan dapat dimatikan kapan saja jika memori
sedang dibutuhkan oleh proses foreground, visible, atau service. Biasanya ada banyak proses
background yang dijalankan, sehingga diletakkan di daftar LRU (Least Recently Used).
Daftar ini digunakan untuk memastikan bahwa proses dengan activity tersebut adalah hal
yang baru saja dilihat oleh pengguna dan activity terakhir yang akan dimatikan. Jika sebuah
activity mengimplementasi method siklus hidupnya dengan tepat dan menangkap kondisi
yang sedang berjalan, maka saat prosesnya dimatikan tidak akan mengganggu
experiencepengguna.
5. Empty Process, merupakan proses yang tidak menjalankan komponen aplikasi yang sedang
aktif. Proses ini tetap dijalankan sebagai cache (media penyimpanan sementara) untuk
meningkatkan performa aplikasi ketika akan dijalankan kembali. Sistem akan mematikan
proses ini untuk menjaga keseimbangan sumber daya keseluruhan antara proses cache dan
cache di kernel. Android membuat daftar prioritas proses, berdasarkan atas kepentingan
komponen aktif yang sedang berjalan di dalam proses. Contohnya, jika sebuah proses
menjalankan service dan visible, maka proses tersebut akan diberikan peringkat sebagai
proses visible, bukan proses service.
Sebagai tambahan, peringkat proses dapat bertambah jika ada proses lain yang bergantung
kepadanya. Sebuah proses yang melayani proses yang lain tidak akan diletakkan pada peringkat
lebih rendah dari proses lain yang dilayaninya. Misalnya, jika content provider di dalam proses
A sedang melayani client pada proses B, atau jika service di dalam proses A terkait pada
komponen di proses B, maka proses A akan selalu dianggap sama pentingnya dengan proses B.
Karena proses yang menjalankan service akan diletakkan pada peringkat yang lebih tinggi
daripada backgroundactivity. Sebuah activity yang mengawali operasi yang membutuhkan waktu
lama akan memulai service untuk menjalankannya, tidak dengan membuat thread baru,
khususnya jika operasi ini akan dimatikan paling akhir di dalam activity. Contohnya, memainkan
musik pada latar atau mengunggah gambar yang baru saja ditangkap kamera ke situs. Dengan
menggunakan service akan menjamin bahwa operasi ini akan mendapatkan prioritas, apapun
Dasar Pemrograman Android
Page 117
yang akan terjadi di dalam activity. sebagaimana dijelaskan pada bagian Siklus Hidup Broadcast
Receiver sebelumnya, maka dengan alasan inilah broadcast receiver sebaiknya menggunakna
service dibandingkan dengan menjalankan operasinya di dalam thread.
Page 118
3.7
Widget View
Selanjutnya, akan dibahas penggunaan komponen-komponen yang ada di Android. Pada
bagian ini akan dibahas mengenai widget view yaitu Text Controls, Button, CheckBox,
RadioButton, Rating Bar, List, Grid, Date, Time, Gallery dan Spinner.
3.7.1 TextControl
Text control adalah tipe pertama dari komponen Android yang akan dipelajari. Pada bagian
ini akan dibahas tentang pengunaan TextView, EditText, AutoCompleteTextView, dan
MultiCompleteTextView.
3.7.2 TextView
Komponen TextView ini dapat menampilkan tulisan di layar tetapi pengguna tidak dapat
mengubah tulisan tersebut. Perlu diketahui bahwa TextView juga dapat membuat autoLink
terhadap URL. Jadi apabila pengguna menekan TextView, maka sistem akan merujuk pada
halaman web dari URL tersebut dengan menggunakan class android.text.util.Linkfy.
Berikut ini adalah potongan kode definisi pebuatan TextView dalam bentuk XML:
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv=new TextView(this);
tv.setText("SEAMEO REGIONAL OPEN LEARNING CENTRE " +
" Komplek Universitas Terbuka " +
" Jl. Cabe Raya,Pondok Cabe Pamulang 15418 "
);
Linkify.addLinks(tv, Linkify.ALL);
setContentView(tv);
}
Page 119
Gambar 3.4 Tampilan link URL dan telepon ketika di tekan pada TextView.
Pada contoh ini, method addLinks() dipanggil dari Linkify. Linkify membuat link dari teks yang
terlihat seperti nomor handphone, email address, web URL, ataupun map address.
3.7.3 EditText
EditText merupakan subclass dari TextView. EditText dapat digunakan untuk mengubah
teks dan juga dapat digunakan untuk memasukkan input berupa angka saja atau membuat kata
kunci.
EditText et =new EditText(this);
et.setText("Ini merupakan salah satu contoh dari EditText");
Page 120
Dari contoh diatas, isi dari EditText juga dapat diubah dengan menggunakan object Spannable.
Teks juga dapat dibuat menjadi bolddan italics, atau diberikan warna background menjadi merah.
Penyuntingan tulisan dengan menggunakan EditText ini juga tidak dibatasi seperti menggunakan
superscript, subscript strikethrough, dan sebagainya.
3.7.4 AutoCompleteTextView
AutoCompleteTextView merupakan TextView dengan fungsi auto-complete. Ketika
pengguna menyentuh huruf, maka akan muncul pilihan menu yang dapat dipilih.
LinearLayout ly=new LinearLayout(this);
TextView txt=new TextView(this);
Page 121
Page 122
Page 123
<Buttonandroid:id="@+id/ccbtn1"
android:text="Basic Button"
android:typeface="serif"
android:textStyle="bold"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
Berikut ini adalah potongan kode pemanggilan button menggunakan code Java:
Button btn = (Button)this.findViewById(R.id.ccbtn1);
btn.setOnClickListener(new OnClickListener(){
publicvoid onClick(View v){
finish();
}
});
Kode diatas menjelaskan tentang bagaimana event ketika button ditekan. Event tersebut
didaftarkan pada method setOnClickListener() dari ClassOnClickListener. Didalam kode,
listener dibuat untuk menangani event ketika button ditekan. Ketika button ditekan method
OnClick()
Page 124
<ImageButtonandroid:id="@+id/imageBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Image dari button juga dapat dibuat secara dinamis melalui method setImageResource() atau
dengan memodifikasi file XML layout dengan menambahkan android: src yang merujuk pada ID
image seprti yang terlihat pada potongan kode berikut.
<ImageButtonandroid:id="@+id/imageBtn"
android:src="@drawable/btnImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Berikut ini adalah potongan kode pemanggilan image button menggunakan kode Java:
ImageButton btn = (ImageButton)this.findViewById(R.id.imageBtn);
btn.setImageResource(R.drawable.icon);
Page 125
android:layout_height="wrap_content"
android:text="Toggle Button"/>
Selain itu, tulisan On-Off tersebut dapat diubah dengan android:textOn dan android:textOff
seperti yang terlihat pada potongan kode berikut.
<ToggleButtonandroid:id="@+id/cctglBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textOn="Run"
android:textOff="Stop"
android:text="Toggle Button"/>
Page 126
<selectorxmlns:android="http://schemas.android.com/apk/res/android">
<itemandroid:drawable="@drawable/android_pressed"
android:state_pressed="true" />
<itemandroid:drawable="@drawable/android_focused"
android:state_focused="true" />
<itemandroid:drawable="@drawable/android_normal" />
</selector>
Source kode di atas mendefinisikan sebuah single drawable resource yang berada pada
drawable dengan dalam kasus ini nama file-nya adalah android_button.xml yang akan mengganti
image berdasarkan status yang berlaku pada saat button ditekan. <item> pertama definisasikan
android_pressed.png sebagai image pada saat button ditekan (diaktifkan); <item> kedua
mendefinisikan android_focused.png sebagai image pada saat button di-highlight; dan <item>
yang ketiga mendefinisasikan android_normal.png sebagai image pada saat tidak sedang aktif.
File XML ini merepresentasikan sebuah single drawable resource dan pada saat button ditekan,
image akan ditampilkan berdasarkan state yang telah diatur pada konfigurasi di atas.
Setelah selesai mendefinisikan selector di atas, selajutnya selector tersebut akan di
panggil dalam layout file XML yang akan ditampilkan.
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/android_button"/>
android:background
Page 127
3.7.6.5 CheckBox
CheckBox memiliki dua keadaan yaitu On dan Off sama seperti ToggleButton. Dalam
pembuatannya di Android, dapat menggunakan class android.widget.CheckBox. Berikut
adalah potongan kode dalam bentuk XML.
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextViewandroid:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Makanan kesukaan :">
</TextView>
<CheckBoxandroid:text="Nasi Goreng"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBoxandroid:text="Nasi Pecel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBoxandroid:text="Nasi Uduk"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<CheckBoxandroid:text="Nasi Kuning"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Page 128
Page 129
android:layout_height="wrap_content"/>
<RadioButtonandroid:id="@+id/pecelRBtn"android:text="Nasi Pecel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</RadioGroup>
</LinearLayout>
Berikut ini adalah potongan kode pemanggilan RadioGroup menggunakan kode Java:
RadioGroup rdgrp = (RadioGroup)findViewById(R.id.rBtnGrp);
RadioButton newRadioBtn = new RadioButton(this);
newRadioBtn.setText("Nasi Kuning");
rdgrp.addView(newRadioBtn);
newRadioBtn.setChecked(true);
bagian
ini,
akan
dijelaskan
bagaimana
membuat
sebuah
widget
yang
Page 130
<TextViewandroid:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nilai anda : "/>
<RatingBarandroid:id="@+id/ratingbar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"android:numStars="5"
android:stepSize="1.0"/>
</LinearLayout>
akan
menampilkan
sebuah
ratingbar
RatingBar.OnRatingBarChangeListener.onRatingChanged().
dengan
memanggil
menekan tombol rating maka akan muncul sebuah Toast untuk menampilkan rating. Hasil
potongan kode di atas adalah sebagai berikut:
Page 131
Berikut ini adalah potongan kode pemanggilan ListView menggunakan kode Java:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] nama = { "Rinal", "Iman", "Andzar", "Regi", "Metra",
"Dexwan", "Esha", "Slamet", "Ade" };
setListAdapter(new ArrayAdapter<String>(this, R.layout.main, nama));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
lv.setOnItemClickListener(null);
}
public void onItemClick(AdapterView<?> arg0, View arg1,
Page 132
Page 133
android:horizontalSpacing="10px"
android:numColumns="auto_fit"
android:columnWidth="100px"
android:stretchMode="columnWidth"
android:gravity="center"/>
Berikut ini adalah potongan kode pemanggilan GridView menggunakan kode Java:
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
GridView gv = (GridView) this.findViewById(R.id.dataGrid);
String kota[] = { "Cimahi", "Bandung", "Jakarta", "Denpasar",
"Surabaya", "Malang", "Semarang", "Pontianak", "Medan", "Aceh",
"Sidoarjo", "Batam", "Tangerang" };
gv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item, kota));
gv.setOnItemClickListener(new OnItemClickListener() {
publicvoid onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3){
Toast.makeText(Main.this, "" + arg2, Toast.LENGTH_SHORT).show();
}
});
}
Page 134
tahun), sedangkan TimePicker untuk mengatur waktu (jam dan menit). Selain dalam bentuk
widget ada pula dalam bentuk dialog dengan fungsi yang sama yaitu DatePickerDialog dan
TimePickerDialog. DatePicker dapat diatur tanggalnya dalam bentuk tahun, bulan , dan hari.
Nilai (values) bulan dari widget DatePicker dimulai dari 0 untuk Januari sampai 11 untuk bulan
Desember. Widget tersebut pun memiliki fungsi objek callback (onDateChangedListener atau
onDateSetListener)
yang berfungsi untuk memberi informasi tanggal yang dipilih atau diatur
oleh pengguna.
Seperti halnya DatePicker, TimePicker pun dapat diatur jamnya dalam bentuk menit
(nilainya 0~59) dan jam (nilainya 0~23). Adapun indikasi saat menggunakan TimePicker adalah
mode 12 jam atau mode 24 jam. TimePicker pun memiliki fungsi objek callback
Dasar Pemrograman Android
Page 135
Berikut ini adalah potongan kode pemanggilan DatePicker dan TimePicker menggunakan kode
Java:
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
DatePicker dp = (DatePicker) this.findViewById(R.id.datePicker);
dp.init(1992, 9, 19, null);
TimePicker tp = (TimePicker) this.findViewById(R.id.timePicker);
tp.setIs24HourView(true);
tp.setCurrentHour(new Integer(10));
tp.setCurrentMinute(new Integer(10));
}
Page 136
Page 137
android:layout_height="wrap_content"
android:text="set Time" />
</LinearLayout>
DateandTimeActivity.java
package coba.latihan;
import java.text.DateFormat;
import java.util.Calendar;
import
import
import
import
import
import
import
import
import
import
android.app.Activity;
android.app.DatePickerDialog;
android.app.TimePickerDialog;
android.os.Bundle;
android.view.View;
android.view.View.OnClickListener;
android.widget.Button;
android.widget.DatePicker;
android.widget.TextView;
android.widget.TimePicker;
Page 138
Page 139
tp.setIs24HourView(true);
tp.setCurrentHour(new Integer(10));
tp.setCurrentMinute(new Integer(10));
}
b.
menampilkan Tanggal dan Waktu. Berikut adalah potongan kode dalam bentuk XML.
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"android:layout_width="fill_parent"
android:layout_height="fill_parent">
<AnalogClockandroid:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<DigitalClockandroid:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
Page 140
Page 141
<ImageView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scaleType="fitXY" />
</LinearLayout>
Berikut ini adalah potongan kode pemanggilan Gallery menggunakan kode Java. Kode ini
diletakkan dalam method onCreate():
Gallery g = (Gallery) findViewById(R.id.galleryCtrl);
g.setAdapter(new ImageAdapter(this));
g.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(getBaseContext(),
""
arg2,Toast.LENGTH_SHORT).show();
ImageView imageView = (ImageView)findViewById(R.id.imageView1);
imageView.setImageResource(mImageIds[arg2]);
}
});
Dimulai dengan dengan mengatur layout dari main.xml sebagai konten dari view dan menangkap
Gallery dari layout dengan findViewById(int). Kemudian BaseAdapter dipanggil, dan
ImageAdapter akan diinstansikan dan ditambahkan pada Gallery dengan setAdapter().
Kemudian
sebuah
AdapterView.OnItemClickListener
akan
diinstansiasikan
Berikut adalah sebuah custom styleable resource yang dapat diaplikasikan pada sebuah layout.
Dalam hal ini, akan diaplikasikan kepada setiap item individual di dalam Gallery.
<?xmlversion="1.0"encoding="utf-8"?>
<resources>
<declare-styleable name="HelloGallery">
Page 142
<attr name="android:galleryItemBackground"/>
</declare-styleable>
</resources>
Elemen <attr> mendefinisikan sebuah atribut spesifik untukstyleable, dan dalam hal ini,
mengacu kepada platformattribute, yaitu galleryItemBackground yang mendefinisikan sebuah
border styling untuk gallery item. Dalam langkah berikutnya, akan terlihat bagaimana atribut ini
direferensikan lalu diaplikasikan kepada setiap item pada Gallery.
Page 143
Page 144
Pertama-tama, ada beberapa variabel, termasuk sebuah array yang berisikan ID yang
mereferensi kepada gambar-gambar yang disimpan di dalam (res/drawable/). Kemudian ada
constructor, di mana Context untuk ImageAdapter didefinisikan di sini, beserta dengan
styleableresource yang didefinisikan pada langkah terakhir dan disimpan di sebuah localfield.
Pada akhir dari constructor, recycle() dipanggil pada TypedArray , agar bisa digunakan
kembali oleh system.
mengatur
Gallery.LayoutParams,
tinggi
dan
lebar
untuk
image
dengan
menggunakan
mengatur background dengan menggunakan atribut styleable yang diperoleh dari constructor.
Page 145
3.7.14 Spinner
Spinner merupakan sebuah widget yang mirip dengan drop-downlist. Pada bagian ini,
akan dijelaskan bagaimana cara membuat sebuah spinner sederhana yang akan menampilkan
nama-nama kota. Pada saat terpilih, maka sebuah pesan akan keluar dengan menampilkan item
yang dipilih.
<?xmlversion="1.0"encoding="utf-8"?>
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="10dip"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dip"
android:text="Nama-nama kota di Indonesia"
/>
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
Perhatikan atribut dari TextView yaitu android:text yang akan berperan sebagai title dari
widget. Pada saat dipasang pada Spinner, maka title akan muncul di selection dialog yang
muncul diatas widget yang di pilih. Selanjutnya adalah menambahkan string-array kedalam
tag <resources></resources> pada file strings.xml yang terdapat pada folder /res/values.
string-array
spinner.
<string-array name="planet_array" >
<item>Bumi</item>
<item>Jupiter</item>
<item>Mars</item>
<item>Merkurius</item>
Page 146
<item>Neptunus</item>
<item>Saturnus</item>
<item>Uranus</item>
<item>Pluto</item>
<item>Venus</item>
</string-array>
Page 147
Setelah layout dari main.xml diatur menjadi content view, Spinner widget akan diterima
dari method findViewById(int). Kemudian method createFromResource() akan membuat
sebuah ArrayAdapter yang baru. ArrayAdapter tersebut akan mengikat setiap item di dalam
stringarray pada awal kemunculan Spinner (item akan keluar setiap saat spinner dipilih).
IDR.array.planets_array
mengacu
android.R.layout.simple_spinner_item
pada
string-array
dan
ID.
Page 148
Deskripsi
LinearLayout
RelativeLayout
TableLayout
FrameLayout
TabLayout
Page 149
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="green"
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="blue"
android:gravity="center_horizontal"
android:background="#0000aa"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="yellow"
android:gravity="center_horizontal"
android:background="#aaaa00"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1">
<TextView
android:text="red"
android:gravity="center_horizontal"
android:background="#aa0000"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="green"
Page 150
android:gravity="center_horizontal"
android:background="#00aa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="blue"
android:gravity="center_horizontal"
android:background="#0000aa"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
<TextView
android:text="yellow"
android:gravity="center_horizontal"
android:background="#aaaa00"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
Ini adalah Linear Layout Android sederhana. Tata letak ini menetapkan orientasi vertikal dan
horizontal. Hasil potongan kode di atas adalah sebagai berikut:
Page 151
a.
ukuran dan posisi, digunakan weight dan gravity. Weight digunakan untuk mengatur besar dan
gravity berfungsi sebagai alignment. Sebagai contoh, jika menginginkan tulisan rata kanan, maka
gravity perlu diatur menjadi right. Contoh beberapa nilai untuk gravity: left, center,right, top,
bottom, center_horizontal, center_vertical dan masih banyak lagi.
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertikal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.0"
android:gravity="left"
android:text="one"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:gravity="center"
android:text="two"/>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0.0"
android:gravity="right"
android:text="three"/>
</LinearLayout>
Page 152
Gambar 3.23 Tampilan Linear Layout yang memiliki pengaturan weight dan gravity.
b.
android:layout_gravity.
view
sedangkan
android:layout_gravity
digunakan
untuk
mengatur
container
Page 153
Table Layout
TableLayout adalah sebuah ViewGroup yang memperlihatkan elemen view dalam bentuk
baris dan kolom. Untuk menggunakan Table Layout, tambahkan Table Layout pada layout XML
kemudian lanjutkan dengan menggunakan Table Row. Table Row digunakan untuk mengatur
elemen pada tabel.
<TableLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"android:layout_height="fill_parent">
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nama Depan:"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Metra"/>
</TableRow>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nama Belakang:"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="C. Utama"/>
</TableRow>
</TableLayout>
Page 154
Page 155
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nama Belakang:"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Metra"/>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"android:text="Utama"/>
</TableRow>
</TableLayout>
Meskipun
pola
Table
android.widget.View
Layout
dengan
elemen
Table
Row
sering
digunakan,
Page 156
android:stretchColumns="0,1,2">
<EditText
android:text="Nama Lengkap:"/>
<TableRow>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Metra"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cahya"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"android:text="Utama"/>
</TableRow>
</TableLayout>
dikarenakan
turunan
dari
Table
android:layout_width=wrap_content.
Layout
EditText
tidak
tersebut
bisa
dipaksa
menentukan
untuk
menerima
fill_parent. Karena isi tabel tidak selalu diketahui pada saat desain, Table Layout menawarkan
beberapa
atribut
yang
dapat
membantu
kita
dalam
mengatur
tata
letak.
Page 157
android:stretchColumns = 0,1,2
0,1,2 dapat diatur berdasarkan isi tabel. android:shrinkColumns dapat digunakan untuk
mengatur isi kolom atau kolom jika kolom lain memerlukan lebih banyak ruang. Selain itu juga
dapat mengatur android:collapseColumns untuk membuat kolom menjadi tidak terlihat.
Catatan bahwa kolom yang diidentifikasi pengindeks-annya berbasis nol.
Kode di atas menampilkan 40 pixel ruang putih antara garis luar EditText dengan teks yang
berada di dalamnya. Gambar dibawah ini menunjukkan perbandingan antara menggunakan
padding dan yang tidak menggunakan padding.
Page 158
android:padding
mengatur padding atau ketebalan untuk semua sisi: kiri, kanan, atas
dan bawah. Selain itu, padding untuk bagian depan juga dapat diatur dengan menggunakan
android:leftPadding,
android:bottomPadding.
android:rightPadding,
android:topPadding
dan
yang
dapat
diilustrasikan
seperti
android:gravity
atau
android:layout_gravity.
Relative Layout
Relative Layout mengatur tata letak komponen dalam hubungan atar satu dengan yang
lainnya. Hal ini memberikan fleksibilitas yang lebih untuk penentuan tata letak dengan
memanfaatkan Linear Layout.
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/penggunaNameLbl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Penggunaname: "
android:layout_alignParentTop="true"/>
<EditText
android:id="@+id/penggunaNameText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/penggunaNameLbl"/>
<TextView
android:id="@+id/pwdLbl"
Page 159
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/penggunaNameText"
android:text="Password: "/>
<EditText
android:id="@+id/pwdText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/pwdLbl"/>
<TextView
android:id="@+id/pwdHintLbl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/pwdText"
android:text="Password Criteria... "/>
<TextView
android:id="@+id/disclaimerLbl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Kevin R. Octavian "/>
</RelativeLayout>
Page 160
Kode di atas menghasilkan program yang menampilkan form seperti yang terlihat pada
gambar 3.9.7. Label username terletak di atas, karena di dalam kode ditetapkan nilai dari
android:layout_alignParentTop
layout
tersebut,
layout
juga
dapat
ditentukan
e.
dengan
layout_above,
Frame Layout
Layout Manager yang dibahas sampai saat ini mengimplementasikan berbagai layout.
Page 161
Page 162
Aspek lain yang menarik dari FrameLayout adalah jika menambahkan lebih dari satu
komponen ke layout, ukuran layout dihitung sebagai ukuran dari item terbesar di container.
f.
Tab Layout
Dalam membuat tabbedUI, digunakan TabHost dan TabWidget. Tabhost harus merupakan
rootnode untuk layout-nya, yang isinya baik TabWidget untuk menampilkan tab atau
FrameLayout untuk menampilkan isi dari tab. Untuk mengimplementasikan isi dari tab bisa
dilakukan dengan dua cara, yaitu dengan menggunakan tab untuk mengganti View dalam Activity
yang sama, atau menggunakan tab untuk mengganti semua activity yang terpisah.
publicclass LaguBarat extends Activity {
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Ini adalah dafatar Lagu Barat");
setContentView(textview);
}
}
publicclass LaguBaru extends Activity {
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Ini adalah dafatar Lagu Baru");
setContentView(textview);
}
}
publicclass LaguLama extends Activity {
publicvoid onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView textview = new TextView(this);
textview.setText("Ini adalah dafatar Lagu Lama");
setContentView(textview);
}}
Page 163
Activity diatas merupakan isi dari setiap tab. Jangan lupa untuk menambahkan setiap
Activity ke dalam AndroidManifest.xml
<activity android:name=".LaguLama"></activity>
<activity android:name=".LaguBaru"></activity>
<activity android:name=".LaguBarat"></activity>
Ini adalah sebuah state-list drawable, hal ini akan digunakan sebagai tabimage. Saat
tabstate berganti, maka tabicon akan berganti secara otomatis (antara aktif atau tidak aktif).
<TabHostxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertikal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="5dp" />
</LinearLayout>
Page 164
</TabHost>
Kode-kode di atas akan menghasilkan layout yang menampilkan semua tab dan mengatur
navigasi pada setiap navigasi yang dibuat.
TabHost membutuhkan baik TabWidget dan FrameLayout untuk bekerja di dalam
TabHost. Untuk memposisikan TabWidget dan FrameLayout secara vertikal, maka diperlukan
sebuah LinearLayout. FrameLayoutmemang merupakan tempat di mana semua konten dari
setiap tab dijalankan, namunmasih tetap dalam keadaan kosong karena TabHost akan langsung
meng-embed setiap Activity di dalamnya. Perhatikan bahwa elemen dari TabWidget dan
FrameLayout memiliki ID dari tab dan tab content secara perspektif.
Resources res = getResources();
TabHost tabHost = getTabHost();
TabHost.TabSpec spec;
Intent intent;
intent = new Intent().setClass(this, LaguLama.class);
spec = tabHost.newTabSpec("artists").setIndicator("Lagulama",
res.getDrawable(R.drawable.tab_btn))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, LaguBaru.class);
spec = tabHost.newTabSpec("albums").setIndicator("Lagubaru",
res.getDrawable(R.drawable.tab_btn))
.setContent(intent);
tabHost.addTab(spec);
intent = new Intent().setClass(this, LaguBarat.class);
spec = tabHost.newTabSpec("songs").setIndicator("Lagubarat",
res.getDrawable(R.drawable.tab_btn))
.setContent(intent);
tabHost.addTab(spec);
tabHost.setCurrentTab(2);
Kode di atas mengatur setiap tab beserta text dan icon serta menempatkan Activity di
masing-masing tab. Sebuah referensi ke TabHost pertama akan ditampilkan menggunakan
getTabHost().
Page 165
setiap tab, dan setContent(Intent) akan dipanggil untuk menspesifikasikan Intent untuk
membuka Activity. Setiap TabHost.TabSpec akan ditambahkan kepada TabHost dengan
memanggil addTab(TabHost.TabSpec). Pada akhirnya, setCurrentTab(int) akan membuka
tab yang akan ditampilkan secara default, dispesifikasikan oleh posisi index dari tab.
Perhatikan bahwa tidak hanya sekali object TabWidget direferensikan. Ini karena
TabWidget selalu merupakan turunan dari TabHost, di mana hampir setiap kali digunakan untuk
berinteraksi dengan tab. Jadi pada saat sebuah tab ditambahkan kepada TabHost, maka akan
secara otomatis ditambahkan kepada child TabWidget.
Penyesuaian Layout
Sekarang sudah diketahui bahwa Android menawarkan sejumlah LayoutManager yang
dapat membantu dalam membangun penggunaan interface. Jika sudah terbiasa dengan layout
manager, maka dapat dengan mudah menggabungkan beberapa layout manager agar
mendapatkan tampilan seperti yang diinginkan. Pengguna dan produsen perangkat mobile yang
semakin canggih, membuat para developer atau pengembang menjadi lebih menantang. Salah
satu tantangannya adalah membangun UI untuk aplikasi yang menampilkan berbagai konfigurasi
di layar.
Dasar Pemrograman Android
Page 166
Sebagai contoh, apa yang akan UI lakukan apabila aplikasi ditampilkan dalam modus
potrait atau landscape?. Android menyediakan beberapa dukungan terhadap kasus ini. Cara
kerjanya Android akan menemukan dan menampilkan layout dari folder tertentu berdasarkan
konfigurasi perangkat. Sebuah perangkat dapat berada dalam salah satu dari ketiga konfigurasi
ini: potrait, landscape dan square.
Untuk memberikan layout yang berbeda, maka harus membuat folder khusus untuk
masing-masing konfigurasi dimana Android akan memuat layout yang sesuai. Seperti yang telah
diketahui, folder default layout terletak di res atau layout. Untuk mendukung tampilan portrait
buatlah folder bernama res/layout-port. Untuk landscape , buatlah folder bernama res/layoutland, dan untuk square, buat sebuah folder res atau layoutsquare.
Perlu perhatikan juga bahwa Android SDK tidak menawarkan API untuk menentukan
konfigurasi dalam memuat sistem dengan hanya memilih folder berdasarkan konfigurasi
perangkat. Namun orientasi perangkat dapat diatur dalam kode, misalnya:
import android.content.pm.ActivityInfo
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
3.8
Adapter
Adapter pada umumnya bertugas mengikat data dengan mudah dan lebih fleksibel.
Adapter
di
Android
yang
android.widget.AdapterView.
GridView,
Spinner
dan
android.widget.ViewGroup
digunakan
untuk
widget
merupakan
turunan
dari
Gallery.
AdapterView
sendiri
merupakan
turunan
dari
Page 167
View
ViewGroup
AdapterView
ListView
GridView
Spinner
Gallery
Adaptor ini mengkonversi baris dalam kursor ke tampilan turunannya. Definisi dari
pandangan turunannya didefinisikan dalam sumber daya XML (parameterlayout). Perhatikan
bahwa baris dalam kursor memungkinkan untuk memiliki banyak kolom, Untuk menetapkan
kolom dan baris yang ingin dipilih pada SimpleCursorAdapter, dapat dilakukan dengan
menetapkan sebuah array nama kolom(menggunakan parameter). Karena setiap kolom yang
terpilih dipetakan ke TextView, maka harus terlebih dahulu menentukan ID terhadap parameter.
Ada pemetaan one-to-one antara kolom yang dipilih dan TextView yang menampilkan data
dalam kolom, sehingga data ke parameter ukurannya sama.
Page 168
3.8.1 ArrayAdapter
ArrayAdapter adalah adapter yang paling sederhana di Android. ArrayAdapter
mengasumsikan bahwa TextView merupakan anggota item (dalam turunannya). Berikut ini
adalah contoh pembuatan ArrayAdapter :
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
this,android.R.layout.contoh_list_item,
new String[]{"Kevin","Renata",Octavian});
Contructor dalam kode ArrayAdapter menciptakan data yang diwakili oleh String, lalu
disimpan ke dalam TextView. Sebagai catatan: android.R.layout.contoh_list_item merujuk
ke TextView yang didefinisikan oleh Android SDK.ArrayAdapter, menyediakan sebuah method
yang berguna apabila data untuk list berasal dari file.
<string-arrayname="planet">
<item>Merkurius</item>
<item>Venus</item>
<item>Bumi</item>
<item>Mars</item>
<item>Jupiter</item>
<item>Saturnus</item>
<item>Uranus</item>
<item>Neptunus</item>
<item>Pluto</item>
</string-array>
Page 169
memungkinkan tidak hanya eksternalisasi isi daftar untuk fileXML, tetapi juga menggunakan
locale version.
3.8.2 Custom Adapters
Adapter di Android begitu mudah digunakan, namun juga memiliki beberapa keterbatasan.
Untuk itu, Android menyediakan abstract class yang disebut Base Adapter yang dapat
diturunkan jika memerlukan custom adapter. Dengan demikian, jika ingin menurunkan Adapter,
dapat langsung menggunakan adapter berikut ini:
a. ArrayAdapters<T>: Ini adalah adapter yang memiliki tingkatan di atas arrayobject. Biasa
digunakan dengan ListView.
b. CursorAdapter : Adapter ini digunakan dalam ListView. Adapter ini menyediakan data
melalui kursor.
c. SimpleAdapter : Seperti namanya, adapter ini adalah adapter yang sederhana. Adapter ini
umumnya digunakan untuk mengisi daftar dengan data statis.
d. ResourceCursorAdapter : Adapter ini merupakan turunan dari CursorAdapter dan biasa
digunakan membuat view atau tampilan dari resource.
e. SimpleCursorAdapter : Adapter ini merupakan turunan dari ResourceCursorAdapter dan
berfungsi membuat TextView atau ImageView dari kolom dalam kursor.
3.9
Menu
Android menyajikan beberapa pola menu seperti menu dari XML dan menu alternatif.
Bahasan ini akan dimulai dengan menggambarkan class dasar yang terlibat dalam kerangka
menu Android. Dalam prosesnya, akan diajarkan cara membuat menu dan item, serta bagaimana
untuk merespon item menu. Class utama dalam yang digunakan adalah android.view.Menu.
Setiap Activity di Android dikaitkan dengan object menu jenis ini, yang dapat berisi sejumlah
menu dan submenu. Item menu ini diwakili oleh android.view.MenuItem dan submenu diwakili
oleh android.view.SubMenu. Gambar dibawah ini bukan merupakan diagram class, tetapi
struktur diagram yang dirancang untuk membantu visualisasi hubungan antar class yang terkait
dengan berbagai menu dan fungsi.
Page 170
Activity
ModuleMenu
Menu
berisi
berisi
MenuItem
berisi
SubMenu
onCreateOptionsMenu()
onOptionsItemSelected()
Menu group item dapat dibuat dengan menetapkan masing masing IDgroup. Beberapa
menu yang membawa IDgroup yang sama dianggap sebagai bagian dari kelompok yang sama.
Selain memuat IDgroup, sebuah menu item juga memuat judul, sebuah IDmenu-item dan IDsortorde. IDsort-order digunakan untuk menentukan urutan item didalam menu. Misalnya, jika satu
item memuat sort-order berjumlah empat dan item yang lain memuat sejumlah sort-order
berjumlah 6, maka item yang pertama akan muncul diatas item kedua di dalam menu.
Tidak banyak rentang order-number yang dicadangkan bagi beberapa jenis menu. Item
yang dianggap kurang penting daripada yang lain, mulai dari 0x30000 dan didefinisikan oleh
konstanMenu.CATEGORY_SECONDARY.
alternatif menu dan kontainer menu yang memiliki perbedaan rentang order number. Sistem
menu dimulai dari 0x20000 dan didefinisikan oleh konstanta Menu.CATEGORY_SYSTEM. Menu
alternatif dimulai dari 0x40000 dan didefinisikan oleh konstanta Menu.CATEGORY_ALTERNATIVE.
Container
menu
dimulai
dari
0x10000
dan
didefinisikan
oleh
konstan
Menu.CATEGORY_CONTAINER.
Page 171
Dalam Android SDK, tidak diperlukan untuk membuat objek menu dari awal. Karena
sebuah Activity dikaitkan dengan single menu. Android menciptakan single menu ini untuk
Activity dan meneruskannya ke method callback onCreateOptionsMenu dari classActivity.
@Override
publicboolean onCreateOptionsMenu(Menu menu){
// mengatur menu items
. . . .
returntrue;
}
Setelah menu item diisi, tambahkan return true dibagian akhir kode untuk menampilkan
menu. Sebaliknya, jika menuliskan return false maka menu tidak akan terlihat. Kode dibawah ini
merupakan contoh bagaimana menambahkan tiga menuitem menggunakan singlegroupID
bersama dengan tambahan IDmenuitem dan IDsort-order.
@Override
publicboolean onCreateOptionsMenu(Menu menu){
//memanggil class dasaruntukmenyertakan menu sistem
super.onCreateOptionsMenu(menu);
menu.add(0 // Group
,1 // item id
,0 //order
,"judul"); // judul
menu.add(0,2,1,"item2");
menu.add(0,3,2,"bersihkan");
//inisangatpentinguntukmenampilkan menu
returntrue;
}
Dalam menjaga sistem menu item yang terpisah dari menu item jenis lain, Android
menambahkan mulai 0x20000 (Seperti yang telah disebutkan sebelumnya, konstan
Menu.CATEGORY_SYSTEM
pertama yang diperlukan untuk menambahkan menuitem adalah IDgroup (integer). Parameter
kedua adalah IDmenu-item yang dikirim kembali ke methodcallback ketika menuitem dipilih.
Parameter ketiga merupakan IDsort-order. Parameter terakhir adalah nama atau judul dari
Page 172
itemmenu tersebut yang dapat menggunakan string melalui file konstan R.java. Kelompok ID ini,
IDmenu-item dan IDsort-order semua opsional, dapat digunakan Menu.NONE jika tidak ingin
menentukan apapun. Berikutnya adalah bekerja dengan menugroups.
@Override
publicboolean onCreateOptionsMenu(Menu menu){
//Group 1
int group1 = 1;
menu.add(group1,1,1,"g1.item1");
menu.add(group1,2,2,"g1.item2");
//Group 2
int group2 = 2;
menu.add(group2,3,3,"g2.item1");
menu.add(group2,4,4,"g2.item2");
returntrue; // ini sangat penting untuk menampilkan menu
}
Perhatikan bagaimana IDmenu-Item dan IDsort-order berdiri sendiri terhadap group. Jadi
apa gunanya group?. Android menyediakan suatu set method yang didasarkan pada IDgroup.
Group menu item dapat dimanipulasi dengan menggunakan method ini:
removeGroup(id);
setGroupCheckable(id, checkable, exclusive);
setGroupEnabled(id,boolean enabled);
setGroupVisible(id,visible);
Method removeGroup menghapus semua menuitem dari group dengan IDgroup. Untuk
mengaktifkan atau menonatifkan menu dalam suatu group tertentu, gunakan method
setGroupEnabled.
dilakukan
dengan
setGroupCheckable,
menggunakan
setGroupVisible.
Kemudian
ada
juga
method
yang fungsinya adalah untuk menunjukkan tanda centang pada item saat
item tersebut dipilih. Bila diterapkan ke group, akan memungkinkan fungsi ini untuk diterapkan
pada semua item menu dalam kelompok tersebut. Jika method di-set, maka hanya satu menu item
dalam group yang diperbolehkan untuk masuk. Item menu lain akan tetap dicentang. Sekarang
sudah diketahui cara untuk mengisi Activity menu utama dengan satu setmenu dan group mereka
sesuai dengan sifatnya. Selanjutnya, akan dilakukan bagaimana menanggapi menu item ini.
Dasar Pemrograman Android
Page 173
Ada beberapa cara untuk menanggapi klik pada menu-item di Android antara lain
menggunakan method OnOptionsItemSelected dari class Activity, menggunakan listener yang
berdiri sendiri, atau dapat menggunakan intent. Ketika sebuah menu item diklik, Android
memanggil method onOptionsItemSelected pada class Activity.
@Override
publicboolean onOptionsItemSelected(MenuItem item){
switch(item.getItemId()) {
}
//untuk menangani item
returntrue;
//untuk sisanya
returnsuper.onOptionsItemSelected(item);
}
Pola kunci disini adalah untuk menguji IDmenuitem melalui method getItemId() pada
class Menu Item dan melakukan apa yang diperlukan. Jika onOptionsItemSelected()
menangani item menu, itu mengembalikan nilai true, Menu event tidak akan lebih diperbanyak.
Untuk menu-item, onOptionsItemSelected() tidak menangani, onOptionsItemselected()
harus memanggil method induk melalui super.onOptionsItemselected(). Implementasi
method onOptionsItemSelected()
berlangsung.
dua
proses.
OnMenuClickListener.
Pada
langkah
pertama,
kita
menerapkan
interface
selanjutnya ke item menu. Ketika item menu diklik, item menu akan memanggil method
onMenuItemClick()
Method onMenuItemClick dipanggil saat menu item telah dipanggil. Kode ini
mengeksekusi
ketika
item
menu
diklik,
bahkan
sebelum
menjalankan
method
Page 174
onOptionsItemSelected.
lainnya akan dieksekusi termasuk method callback onOptionsItemselected. Ini berarti bahwa
kode listener diutamakan atas method onOptionsItemselected.
3.10 Dialog
Sebelum memulai pokok bahasan ini, coba perhatikan penjelasan berikut tentang dialog.
Pada lingkungan sosial manusia, dialog berjalan seimbang, sebagai contoh, otak hanya berfungsi
melakukan percakapan. Namun konsep dialog di atas berbeda dengan konsep dialog pada
Android. Pada Android diperlukan pola pikir yang berbeda dari contoh dan penjelasan di atas.
Dialog di Android berjalan tidak seimbang, yang dimaksud dengan tidak seimbang ini
adalah seolah-olah bagian depan otak sedang melakukan percakapan, sedangkan bagian belakang
otak berpikir untuk sesuatu yang lain. Tentu saja dialog yang tidak seimbang inisulit dilakukan
pada manusia, namun "split-brain" dapat dilakukan pada program komputer. Dengan
menggunakan pendekatan yang tidak seimbang tersebut, maka program dapat berjalan dengan
lebih efektif lagi, sistem seperti ini juga dapat mengoptimalkan kinerja memori.
Pada bagian berikut akan membahas aspek-aspek dialog Android secara mendalam. Akan
dijelaskan juga apa saja komponen dialog dasar seperti alert dialog dan menunjukkan bagaimana
cara untuk membuat dan menggunakannya. Kemudian juga akan ditunjukkan cara untuk bekerja
dengan prompt dialog yang meminta pengguna untuk memasukkan input dan menampilkan
kembali apa yang telah dimasukkan oleh pengguna dan akan dibahas bagaimana cara memuat
layout ke dalam dialog.
Page 175
Main.this.finish();
}
})
.setNegativeButton("Tidak",
new DialogInterface.OnClickListener() {
publicvoid onClick(DialogInterface dialog, int id) {
dialog.cancel();
}
});
AlertDialog alert = builder.create();
alert.show();
Pada setiap AlertDialoghanya disediakan tiga tombol, yaitu positif, netral, dan negatif.
Nama-nama ini secara teknis tidak bersangkutan dengan fungsi tombol yang sebenarnya, tetapi
akan sangat membantu untuk melakukan sesuatu untuk aplikasi yang dibuat.
tambahkan daftar item yang dapat dipilih dengan setItems() untuk menerima data array yang
berfungsi untuk menampilkan DialogInterface.OnClickListener yang bertugas untuk
mendefinisikan tindakan yang dilakukan pada saat pengguna memilih item.
final CharSequence[] warna = {"Merah", "Kuning", "Hijau" , "Biru"};
Page 176
Dalam membuat daftar beberapa checkbox atau radio button di dalam dialog, dapat
digunakan method setMultiChoiceItems() dan setSingleChoiceItems().
final CharSequence[] warna = {"Merah", "Kuning", "Hijau" , "Biru"};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Pilih warna favorit mu");
builder.setSingleChoiceItems(warna,-1,newDialogInterface.OnClickListener() {
publicvoid onClick(DialogInterface dialog, int item) {
Toast.makeText(getApplicationContext(),warna[item],
Toast.LENGTH_SHORT).show();
}
Page 177
});
AlertDialog alert = builder.create();
alert.show();
Page 178
Page 179
Kebanyakan, kode yang digunakan untuk membuat sebuah progress dialog sebenarnya
juga terlibat dalam proses tersebut. Mungkin dapat disimpulkan bahwa perlu membuat dua
thread dalam aplikasi untuk menangani hal ini, dan kemudian melaporkan kembali ke thread
utama dengan object Handler. Jika tidak terbiasa dengan menggunakan thread dengan Handler,
maka dapat mengikuti contoh berikut ini.
staticfinalintPROGRESS_DIALOG = 0;
Button button;
ProgressThread progressThread;
ProgressDialog progressDialog;
publicvoid onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup the button that starts the progress dialog
button = (Button) findViewById(R.id.btn);
button.setText("Mulai");
button.setOnClickListener(new OnClickListener(){
publicvoid onClick(View v){
showDialog(PROGRESS_DIALOG);
}
});
}
Page 180
Page 181
Thread.sleep(100);
} catch (InterruptedException e) {
Log.e("ERROR", "Thread Interrupted");
}
Message msg = mHandler.obtainMessage();
Bundle b = new Bundle();
b.putInt("total", total);
msg.setData(b);
mHandler.sendMessage(msg);
total++;
}
}
// digunakan untuk menghentikan thread
publicvoid setState(int state) {
mState = state;
}
}
Page 182
Dalam pembuatan custom dialog, diperlukan setidaknya satu buah file xml yang berfungsi
sebagai layout pada custom dialog.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
>
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#FFF"
/>
</LinearLayout>
Setelah layout dibuat, maka sisipkan kode berikut pada activity yang akan menampilkan dialog.
dialog = new Dialog(this);
dialog.setContentView(R.layout.custom_dialog);
dialog.setTitle("Custom Dialog");
TextView text = (TextView) dialog.findViewById(R.id.text);
text.setText("Halo, ini adalah custom dialog!");
ImageView image = (ImageView) dialog.findViewById(R.id.image);
image.setImageResource(R.drawable.honeycomb);
dialog.show();
Page 183
Animasi frame-by-frame, yang terjadi ketika serangkaian frame digambar satu demi satu
pada interval reguler;
b.
Animasi tata letak, yaitu mengubah pandangan dari sudut pandang container seperti daftar
dan tabel,
c.
Animasi visual, yaitu mengubah tampilan dari general purpose. Dua jenis terakhir masuk ke
dalam kategori animasi Tweening, yang melibatkan gambar di antara gambar kunci.
Page 184
Langkah awal, masukkan gambar yang ingin diberikan efek animasi pada folder drawable,
seperti gambar berikut:
Page 185
Page 186
android:duration="50"/>
<item android:drawable="@drawable/h1"
android:duration="50"/>
<item android:drawable="@drawable/h2"
android:duration="50"/>
</animation-list>
Page 187
Tentukan semua nilai parameter yang terkait dengan animasi, yaitu nilai pada saat awal
dan akhir animasi. Setiap animasi juga memungkinkan baik durasi sebagai argumen maupun
waktu interpolator sebagai argumen. Interpolator akan dibahas pada akhir dari bagian ini, tetapi
untuk sekarang, bisa diketahui bahwa interpolators menentukan laju perubahan argumen animasi
Dasar Pemrograman Android
Page 188
selama animasi ditampilkan. Berikutnya definisikan animasi ini sebagai file XML dalam
subdirektori /res/anim.
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator">
<scale
android:fromXScale="1"
android:toXScale="1"
android:fromYScale="0.1"
android:toYScale="1.0"
android:duration="500"
android:pivotX="50%"
android:pivotY="50%"
android:startOffset="100"/>
</set>
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setupListView();
}
private void setupListView()
{
String[] listItems = new String[] {
"Pilihan 1", "Pilihan 2", " Pilihan 3",
" Pilihan 4", " Pilihan 5", " Pilihan 6",
};
ArrayAdapter listItemAdapter =
new ArrayAdapter(this
,android.R.layout.simple_list_item_1
,listItems);
ListView lv = (ListView)this.findViewById(R.id.list_view_id);
lv.setAdapter(listItemAdapter);
}
Berikut tampilannya:
Dasar Pemrograman Android
Page 189
File animasi berada dalam subdirektori /res/anim. Berikutnya marilah memahami arti
dari file XML di atas. Di sini, perbesaran dimulai pada 1 dan tetap pada 1 di sumbu x. Ini berarti
daftar item tidak akan beranimasi menjadi besar/menjadi kecil pada sumbu x.
Namun, pada sumbu y, perbesaran dimulai pada 0,1 dan membesar sampai 1,0. Dengan
kata lain, objek yang beranimasi mulai dari sepersepuluh ukuran normal dan kemudian tumbuh
menjadi ukuran normal. Scaling akan memerlukan waktu 500 milidetik untuk selesai. Nilai
startOffset mengacu pada jumlah milidetik sebelum memulai animasi.
memungkinkan untuk menampilkan lebih dari satu animasi, namun intuk saat ini hanya akan
ditunjukkan satu contoh saja.
Nama file berikut ini adalah scale.xml, tempatkan di subdirektori /res/anim. Untuk
sementara belum diperlukan untuk mengatur file ini sebagai argumen ke ListView, ListView
pertama membutuhkan file XML lain yang bertindak sebagai mediator antara dirinya dan set
animasi.
Page 190
Selain itu diperlukan tempat file XML dalam subdirektori /res/anim. Berikutnya buat
sebuah file XML dengan nama list_layout_controller. Dengan hanya melihat nama dari file ini,
tentu sudah bisa dipastikan mengapa file ini diperlukan dan apa fungsinya. File XML
menetapkan bahwa animasi dalam daftar tersebut harus dilanjutkan secara terbalik, dan bahwa
animasi untuk setiap item harus dimulai setelah delay 30 persen dari total durasi animasi. File
XML ini juga merujuk ke file animasi individu, scale.xml. Juga perhatikan bahwa nama file,
kode menggunakan referensi sumber daya @anim/skala.
<?xmlversion="1.0"encoding="utf-8"?>
<!-- filename: /res/layout/list_layout.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertikal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:id="@+id/list_view_id"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:persistentDrawingCache="animation|scrolling"
android:layoutAnimation="@anim/list_layout_controller"
/>
</LinearLayout>
android:layoutAnimation
Page 191
package. Apabila sekarang aplikasi dijalankan, maka akan terlihat animasi skala pada masingmasing item. Sebelumnya juga telah ditetapkan durasi 500 milidetik sehingga skala yang berubah
dapat diamati dengan jelas. Sekarang mari coba bereksperimen dengan jenis animasi yang
berbeda. Berikutnya mari mencoba animasi alpha.
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="1000" />
Page 192
Perhatikan bagaimana telah ditetapkan dua animasi dalam satu animasi. Animasi akan
memindahkan teks dari atas ke bawah layar. Animasi alpha akan mengubah gradien warna dari
terlihat terlihat sebagai teks item turun ke dalam slot-nya.
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android"
android:delay="30%"
android:animationOrder="reverse"
android:animation="@anim/transalate_alpha" />
Page 193
Page 194
dengan cara pada saat memulai contoh di bagian "Layout Animation". Kemudian membuat
sebuah tombol di bagian atas layar untuk memulai animasi ListView saat diklik. Ketika tombol
mulai animasi diklik, maka akan terlihat animasi gambar yang mengecil di tengah layar dan
secara bertahap menjadi lebih besar sampai memenuhi semua layar.
<?xmlversion="1.0"encoding="utf-8"?>
<!-- This file is at /res/layout/list_layout.xml -->
<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertikal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<Button
android:id="@+id/btn_animate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Jalankan animasi"
/>
<ListView
android:id="@+id/list_view_id"
android:persistentDrawingCache="animation|scrolling"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
Perhatikan bahwa lokasi file dan nama file yang tertanam di bagian atas dari file XML
untuk referensi. Layout ini memiliki dua bagian: pertama adalah tombol yang bernama
btn_animate untuk menghidupkan animasi, dan yang kedua adalah ListView, yang bernama
list_view_id. Sekarang kita memiliki layout untuk Activity ini, kita dapat membuat Activity untuk
menunjukkan melihat dan mengatur tombol Animasi.
@Override
publicvoid onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Page 195
setContentView(R.layout.main);
setupListView();
this.setupButton();
}
privatevoid setupListView()
{
String[] listItems = new String[] {
"Item 1", "Item 2", "Item 3",
"Item 4", "Item 5", "Item 6",
};
ArrayAdapter listItemAdapter =
new ArrayAdapter(this
,android.R.layout.simple_list_item_1
,listItems);
ListView lv = (ListView)this.findViewById(R.id.list_view_id);
lv.setAdapter(listItemAdapter);
}
privatevoid setupButton()
{
Button b = (Button)this.findViewById(R.id.btn_animate);
b.setOnClickListener(
new Button.OnClickListener(){
publicvoid onClick(View v)
{
animateListView();
}
});
}
privatevoid animateListView()
{
ListView lv = (ListView)this.findViewById(R.id.list_view_id);
lv.startAnimation(new ViewAnimation());
}
Tujuan dari contoh ini adalah untuk menambahkan animasi ke ListView. Untuk
melakukan
hal
itu,
maka
diperlukan
oleh
class
yang
berasal
dari
Page 196
Page 197
Page 198