Dasar Pemrograman Android PDF
Dasar Pemrograman Android PDF
3.2 Tujuan
Setelah mempelajari tutorial ini, pembaca diharapkan dapat:
a. Memahami dasar pemrograman Android.
b. Mengetahui dan memahami komponen yang ada pada aplikasi Android.
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.
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,
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
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
Sebuah started services merupakan salah satu komponen starts dengan memanggil
startService(), menghasilkan sebuah panggilan ke method onStartCommand(). Ketika
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(), atau komponen lain dapat menghentikannya dengan memanggil stopServices().
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() untuk startService(). Services menerima intent di
onStartCommand(), menghubungkan ke internet dan melakukan transaksi database. Setelah
transaksi dilakukan, services berhenti sendiri dan akan dihancurkan.
Ada dua class yang dapat di extends untuk membuat sebuah services.
a. Services
Merupakan class daras untuk semua services. Ketika mengextends class ini, penting
utnuk membuat thread baru sebagai tempat kerja services, karena services ini
menggunakan thread utama dari aplikasi yang dibuat, secara default dapat memperlambat
kinerja dari setiap aktivitas aplikasi yang berjalan.
b. IntentServices
Merupakan subclass dari Services yang menggunakan thread untuk menangani semua
permintaan awal satu per satu. Merupakan pilihan terbaik jika services yang ditangani
tidak memerlukan beberapa request secara bersamaan. Yang harus dilakukan adalah
mengimplementasikan onHandleIntent(), yang menerima intent untuk setiap request
sehingga dapat melakukan background work.
/**
* A constructor is required, and must call the super
IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}
/**
* The IntentService calls this method from the default worker thread
with
* the intent that started the service. When this method returns,
IntentService
Jika akan meng override method callback, seperti onCreate(), onStartCommand() atau
onDestroy(), pastikan untuk memanggil implementasi super, sehingga IntentServices dapat
menangani worker thread. Sebagai contoh, onStartCommand() harus mengembalikan
implementasi standar (bagaimana intent mengirim ke onHandleIntent()) :
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
Selain onHandleIntent(), method yang tidak dibutuhkan untuk memanggil super class
adalah onBind() (tapi dibutuhkan jika services mengizinkan binding).
@Override
public void onCreate() {
// Start up the thread running the service. Note that we create a
// separate thread because the service normally runs in the process's
// main thread, which we don't want to block. We also make it
// background priority so CPU-intensive work will not disrupt our UI.
HandlerThread thread = new HandlerThread("ServiceStartArguments",
Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting",
Toast.LENGTH_SHORT).show();
@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();
}
}
START STICKY
Jika sistem mematikan services setelah onStartCommand() dikembalikan, membuat ulang
services dan memanggil onStartCommand(), tetapi tidak mengirimkan kembali intent terakhir.
Melainkan, sistem memanggil onStartCommand() dengan sebuah null intent, meskipun terdapat
intent yang tertunda untuk memulai services, pada kasus intent tersebut dikirimkan. Cocok
Starting a Service
Sebuah services dari activity atau komponen aplikasi lain dapat dijalankan dengan
melewatkan sebuah intent ke startService(). Sistem Android memanggil method
onStartCommand() dan melewatkan intent. (Jangan memanggil onStartCommand() secara
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);
@Override
public void onCreate() {
// The service is being created
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(). Contoh: sebuah services pemutar musik dapat membuat thread dimana
music akan di mainkan di onCreate(), kemudian menghentikan thread pada
onDestroy(). Method onCreate() dan onDestroy() di panggil untuk seluruh services,
baik services yang dibuat oleh startService() maupun bindService().
b. Active lifetime dari services dimulai dengan memanggil onStartCommand() atau
onBind(). Setiap method ditangani oleh Intent yang melewatkan masing-masing
startService() atau bindService().
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() (dengan klien memanggil startService()) dapat menerima sebuah
panggilan untuk onBind() (ketika klien memanggil bindService()).
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
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.
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 kembali ketika activity restart. Method
Activity.startManagingCursor() digunakan untuk memulai pengelolaan dari objek cursor.
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,
d. Broadcast Receiver
Merupakan sebuah component yang menerima dan merespon broadcast announcement
(siaran pemberitahuan). Banyak broadcast yang berasal dari kode sistem, contohnya,
pemberitahuan bahwa zona waktu telah berubah, baterai lemah, baru saja ada pengambilan
gambar, atau user baru saja mengganti pengaturan bahasa. Aplikasi juga dapat menginisiasi
broadcast-contohnya, untuk memberi tahu aplikasi lain bahwa suatu data telah diunduh ke
dalam perangkat dan siap digunakan.
Sebuah aplikasi dapat memperoleh beberapa broadcast receiver untuk merespon
pemberitahuan yang dianggap penting. Setiap receiver meng-extend class
BroadcastReceiver dan dikirim sebagai sebuah objek Intent.
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.
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.
Sebuah component dapat memiliki beberapa intent filter, yang setiapnya mendeklarasikan
kemampuan yang berbeda-beda. Jika sebuah component tidak mempunyai filter apapun, maka
component dapat diaktifkan oleh intent yang langsung menunjuk component tersebut sebagai
tujuannya. Intent filter dapat diinstansi secara langsung sebagai IntentFilter obyek
untukbroadcast receiver yang dibuat dan dinyatakan dalam kode. Semua filter yang lain diatur di
dalam manifest.
Tiga komponen penting dari aplikasi Android adalah activities, services, dan broadcast
receivers. Intent diaktifkan dengan dipanggil melalui pesan. Pesan Intent adalah fasilitas untuk
akhir run-time yang mengikat antara komponen dalam aplikasi yang sama atau berbeda. Intent
sendiri adalah struktur data pasif memegang deskripsi abstrak dari operasi yang akan dilakukan,
atau sering disebut dengan kasus broadcast. Deskripsi dari sesuatu yang telah terjadi dan sedang
diumumkan. Ada mekanisme terpisah untuk menyampaikan intent untuk setiap jenis komponen:
Dalam setiap kasus, sistem Android menemukan activity yang sesuai, services, atau
broadcast receivers untuk menanggapi Intent, menginisiasi jika diperlukan. Tidak ada tumpang
tindih dalam sistem ini: maksud Broadcast dikirim hanya untuk menyiarkan pada penerima,
tidak pernah dengan activity atau services. Intent dilewatkan ke startActivity() yang disampaikan
hanya untuk suatu activity, tidak pernah ke penerima services atau broadcast, dan sebagainya.
Dokumen ini dimulai dengan deskripsi objek Intent. Kemudian menggambarkan aturan
Android yang digunakan untuk memetakan komponen intent - bagaimana menyelesaikan
komponen yang harus menerima pesan. Untuk Intent yang tidak secara eksplisit nama komponen
sasaran, proses ini melibatkan pengujian terhadap objek Intent filter terkait dengan target
potensial.
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
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:
Table 3.1 Action
Constant Target Component Action
ACTION_CALL Activity Melakukan Panggilan Telepon
ACTION_EDIT activity Menampilkan data bagi pengguna untuk
mengedit.
ACTION_MAIN activity Start up sebagai kegiatan awal tugas, tanpa
data input dan ada output dikembalikan.
ACTION_SYNC activity Menyinkronkan data pada server dengan
data pada perangkat mobile.
ACTION_BATTERY_LOW broadcast receiver Sebuah peringatan bahwa baterai rendah.
ACTION_HEADSET_PLUG broadcast receiver Headset telah terpasang ke dalam
perangkat, atau dicabut dari itu.
ACTION_SCREEN_ON broadcast receiver Layar telah diaktifkan.
ACTION_TIMEZONE_CHANGED broadcast receiver Pengaturan untuk zona waktu telah
berubah.
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
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 dengan tambahan tertentu. Misalnya, Intent
ACTION_TIMEZONE_CHANGED memiliki "zona waktu" ekstra yang mengidentifikasi zona waktu
baru, dan ACTION_HEADSET_PLUG memiliki "kondisi" ekstra menunjukkan apakah headset
sekarang ditancapkan atau dicabut, serta "nama" tambahan untuk jenis headset. Untuk
menciptakan tindakan SHOW_COLOR, nilai warna akan ditetapkan dalam sebuah pasangan key-
value ekstra.
Obyek Intent memiliki serangkaian method put() untuk memasukkan berbagai jenis data
tambahan dan satu set of get() untuk membaca data. Metode-metode paralel yang untuk
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.
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
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 terdaftar secara dinamis dengan menghubungi
Context.registerReceiver(), mereka langsung dibuat sebagai objek IntentFilter).
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:
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,
Untuk Intent yang lulus tes kategori, setiap kategori di objek Intent harus sesuai kategori
dalam filter. Filter bisa daftar kategori tambahan, tetapi tidak dapat menghilangkan yang Intent.
Karena itu, obyek Intent tanpa kategori harus selalu lulus tes ini, terlepas dari apa yang ada di
filter. Itu sebagian besar benar. Namun, dengan satu pengecualian, Android memperlakukan
semua Intent implisit dilewatkan ke startActivity () seolah-olah mereka mengandung setidaknya
satu kategori: "android.intent.category.DEFAULT" (yang CATEGORY_DEFAULT konstan).
Oleh karena itu, kegiatan yang bersedia untuk menerima inten implisit harus mencakup
"android.intent.category.DEFAULT" di intent filter mereka. (Filter dengan
"android.intent.action.MAIN" dan "android.intent.category.LAUNCHER" Pengaturan adalah
pengecualian menandai kegiatan yang dimulai dengan tugas baru dan diwakili pada layar
peluncur. Mereka dapat termasuk "android.intent category.DEFAULT ". dalam daftar kategori,
tetapi tidak perlu) Lihat Menggunakan penyesuaian intent.
Data Test
Seperti aksi dan kategori, spesifikasi data filter intent yang terkandung dalam sebuah
subelement. Dan, seperti dalam kasus-kasus, subelement dapat muncul beberapa kali, atau tidak
sama sekali. Sebagai contoh:
<intent-filter . . . >
<data android:mimeType="video/mpeg" android:scheme="http" . . . />
<data android:mimeType="audio/mpeg" android:scheme="http" . . . />
. . .
</intent-filter>
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
content://com.example.project:200/folder/subfolder/etc
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,
a. Flag FLAG_ACTIVITY_NEW_TASK
b. Atribut allowTaskReparenting
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> ke dalam atribut launchMode:
a. standard(mode default)
b. singleTop
c. singleTask
d. singleInstance
Bagi mode standard dan singleTop, task yang berasal dari intent (dan dipanggil
startActivity() )- kecuali intent object tersebut mempunyai flag FLAG_ACTIVITY_NEW_TASK.
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.
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
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.
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.
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
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
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.
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.
Antar muka RPC hanya dapat berisi method. Secara default, semua method dieksekusi
secara sinkron (method lokal akan memblokir hingga method remote selesai dilakukan), bahkan
jika tidak ada pengembalian nilai.
Secara singkat, mekanisme kerjanya adalah sebagai berikut: Pertama-tama mulai dengan
mendeklarasikan antar muka RPC yang akan diimplementasikan dengan menggunakan IDL
(Interface Definition Language). Berdasarkan deklarasi tersebut, tool AIDL (Android Interface
Definition Language) akan menghasilkan (generate) definisi interface yang harus tersedia untk
digunakan oleh method lokal dan remote.
Inner class mempunyai semua kode yang dibutuhkan untuk mengatur RPC atas interface
yang dideklarasikan menggunakan IDL. Kedua inner class tersebut mengimplementasikan antar
muka IBinder . Satu inner class digunakan secara lokal dan intern oleh sistem. Inner class yang
lainnya, yang disebut Stub, akan meng-extend kelas Binder. Class ini berisi deklarasi method
dalam antar muka RPC yang telah dideklarasikan sebelumnya yang akan digunakan untuk
melaksanakan pemanggilan IPC. Lalu membuat turunan (subclass) Stub untuk
mengimplementasikan semua method.
Secara khusus, proses remote akan diatur oleh sebuah service (karena service dapat
memberitahukan kepada sistem tentang proses dan hubungannya dengan prosesyang lain).
Service ini akan mempunyai file interface yang dihasilkan oleh toolAIDL dan turunan Stub yang
akan diimplementasikan oleh method RPC. Penerima service (client) hanya akan mempunyai
Contohnya, ketika service dijalankan, method onBind() akan dipanggil dari thread utama
yang ada di dalam proses, method yang diimplementasikan di dalam object yang dikembalikan
onBind() 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.
a. Active, ketika ada di permukaan layar (di atas tumpukan activity pada task yang saat itu
sedang berjalan). Activity inilah yang berkonsentrasi pada aksi dari pengguna.
b. Pause, ketika tidak lagi berkonsentrasi pada pengguna namun tetap tampil di layar. Adanya
activity lain yang tampil di atasnya, activity tersebut bisa tampil secara transparan atau tidak
memenuhi tampil full screen, sehingga beberapa activity yang berstatus pause tetap dapat
terlihat. Activity berstatus pause tetap berjalan (menjaga semua kondisi, informasi, dan tetap
terkait pada window manager), namun dapat dinonaktifkan oleh sistem kapan saja pada saat
memori lemah.
c. Stop, ketika terhalangi sepenuhnya oleh activity lain. Pada status ini, kondisi dan semua
informasi tetap berjalan. Namun, activity tidak terlihat oleh pengguna dan akan dinonaktifkan
oleh sistem ketika memori dibutuhkan di lokasi yang lain. Jika sebuah activity berstatus
pause atau stop, maka sistem dapat menyingkirkannya dari memori dengan cara memanggil
method finish() atau menonaktifkannya begitu saja. Ketika activity tersebut dipanggil lagi
oleh pengguna, maka activity akan di-restart dan dikembalikan (restore) pada kondisi
sebelumnya.
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()
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
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.
Tabel berikut ini akan menunjukkan method tersebut secara rinci dan menjelaskan lokasi method
di dalam siklus hidup activity.
Dapat
Method Deskripsi Selanjutnya
dihentikan?
onCreate() Dipanggil ketika activity pertama dibuat. Tidak onStart()
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()) dinyatakan Ya. Karena onPause() disebutkan pertama kali di antara ketiganya,
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.
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
diputar dan memainkannya.
3. Tidak ada pemanggilan yang sama ketika service dihentikan, tidak ada method onStop().
Method onCreate() dan onDestroy() dipanggil untuk semua service, baik dimulai oleh
Context.startService() maupun Context.bindService(). Namun, onStart() hanya
akan dipanggil untuk service yang dimulai oleh method startService().
4. Jika sebuah service mengizinkan service lain untuk mengadakan koneksi, maka method
tambahan untuk diimplementasi adalah sebagai berikut:
a. IBinder onBind (Intent intent)
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().
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 baru dan kembali, maka proses
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.
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.
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
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:
super.onCreate(savedInstanceState);
Linkify.addLinks(tv, Linkify.ALL);
setContentView(tv);
Ketika link URL dan link telepon ditekan hasilnya seperti gambar berikut:
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.
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.
Pada kode diatas, AutoCompleteTextView menunjukkan daftar kota kepada pengguna. Sebagai
contoh, jika pengguna mengetik kataci, komponen menunjukkan kepada Cimahi. Dan apabila
pengguna mengetik kataba,maka akan muncul Bandung, Bali, Balikpapan dan lainnya.
3.7.5 MultiAutoCompleteTextView
Cara menggunakan MultiAutoCompleteTextView sama seperti AutoCompleteTextView.
Perbedaannya adalah dapat memilih lebih dari satu kata dengan menggunakan tanda koma.
Sebagai contoh, ketika mengetikkata cidan memilih Cimahi. Setelah itu diberi tanda koma,
kemudian mengetikkan kata bamaka akan muncul pilihan Bandung, Bali, Balikpapan, dst.
3.7.6 Button
Pada bagian ini, akan dibahas empat jenis button yang sering digunakan dalam
mengembangkan aplikasi di Android. Button tersebut antara lain Basic Button, Image Button,
Toggle Button dan Custom Button.
Berikut ini adalah potongan kode pemanggilan button menggunakan code Java:
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() otomatis langsung dieksekusi.
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:
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"/>
Berikut dapat dilihat potongan kode pembuatan Custom Button pada file XML:
<?xmlversion="1.0"encoding="utf-8"?>
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.
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:background="@drawable/android_button"/>
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>
3.7.7 RadioButton
RadioButton memberikan pilihan kepada pengguna, namun pengguna hanya dapat memilih
satu item saja. Untuk membuat group dari RadioButton, pertama buat RadioGroup kemudian
tambahkan RadioButton ke dalam group.
<?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>
<RadioGroupandroid:id="@+id/rBtnGrp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButtonandroid:id="@+id/gorengRBtn"android:text="Nasi Goreng"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<RadioButtonandroid:id="@+id/udukRBtn"android:text="Nasi Uduk"
android:layout_width="wrap_content"
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);
3.7.8 RatingBar
Pada bagian ini, akan dijelaskan bagaimana membuat sebuah widget yang
memperbolehkan pengguna untuk menambahkan rating, dengan widget RatingBar. 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">
3.7.9 ListView
ListView berfungsi untuk menampilkan list dari sekumpulan item secara vertikal. Pada
umumnya, ListView ditulis pada Activity yang meng-extend Android.app.ListActivity.
<?xmlversion="1.0"encoding="utf-8"?>
<TextViewxmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp">
</TextView>
Berikut ini adalah potongan kode pemanggilan ListView menggunakan kode Java:
3.7.10 GridView
Android memiliki GridView yang dapat menampilkan data dalam bentuk grid. Data yang
ditampilkan dapat berupa teks, gambar, dan lain-lain. GridView menampilkan informasi berupa
grid. Berikut adalah potongan kode dalam bentuk XML.
<?xmlversion="1.0"encoding="utf-8"?>
<GridViewxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dataGrid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10px"
android:verticalSpacing="10px"
Berikut ini adalah potongan kode pemanggilan GridView menggunakan kode Java:
Berikut ini adalah potongan kode pemanggilan DatePicker dan TimePicker menggunakan kode
Java:
Untuk memodifikasi tampilan DatePicker dan TimePicker menjadi lebih kompleks, dapat
menggunakan kode seperti di bawah ini.
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/lblDateAndTime"
android:layout_width="fill_parent"
android:layout_height="47px"
android:background="#ff000099"
android:textStyle="bold"
>
</TextView>
<Button
android:id="@+id/buttonDate"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="set Date" />
<Button
android:id="@+id/buttonTime"
android:layout_width="fill_parent"
DateandTimeActivity.java
package coba.latihan;
import java.text.DateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.app.DatePickerDialog;
import android.app.TimePickerDialog;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.TextView;
import android.widget.TimePicker;
@Override
public void onDateSet(DatePicker view, int year, int
monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub
myCalendar.set(Calendar.YEAR, year);
myCalendar.set(Calendar.MONTH, monthOfYear);
myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updatelabel();
}
};
TimePickerDialog.OnTimeSetListener t = new
TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int
minute) {
lblDateAndTime.setText(fmtDateAndTime.format(myCalendar.getTime()));
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lblDateAndTime = (TextView) findViewById(R.id.lblDateAndTime);
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new DatePickerDialog(DateandTimeActivity.this,
d, myCalendar.get(Calendar.YEAR),
myCalendar.get(Calendar.MONTH),
myCalendar.get(Calendar.DAY_OF_MONTH)).show();
}
});
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new TimePickerDialog(DateandTimeActivity.this, t,
myCalendar.get(Calendar.HOUR_OF_DAY),
myCalendar.get(Calendar.MINUTE),
true).show();
}
});
updatelabel();
}
} dp.init(1992, 9, 19, null);
TimePicker tp = (TimePicker) this.findViewById(R.id.timePicker);
<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>
Dapat dilihat di atas bahwa AnalogClock pada Android memiliki dua jarum jam yang berfungsi
untuk menunjukkan jam dan menit. Selain itu, terdapat DigitalClock untuk menampilkan waktu
dalam bentuk digital.
3.7.13 Gallery
Gallery adalah sebuah layoutwidget yang digunakan untuk menampilkan item secara
horizontal dan memposisikan item yang sedang dipilih pada bagian tengah screen. Berikut
adalah potongan kode dalam bentuk XML.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Gallery xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/galleryCtrl"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
Berikut ini adalah potongan kode pemanggilan Gallery menggunakan kode Java. Kode ini
diletakkan dalam method onCreate():
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
onItemClick(AdapterView, View, int, long).
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">
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.
public ImageAdapter(Context c) {
mContext = c;
TypedArray a =
obtainStyledAttributes(R.styleable.HelloGallery);
mGalleryItemBackground = a.getResourceId(
R.styleable.HelloGallery_android_galleryItemBackground, 0);
a.recycle();
}
publicint getCount() {
return mImageIds.length;
}
public Object getItem(int position) {
return position;
}
Public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView i = new ImageView(mContext);
i.setImageResource(mImageIds[position]);
i.setLayoutParams(new Gallery.LayoutParams(150, 100));
i.setScaleType(ImageView.ScaleType.FIT_XY);
i.setBackgroundResource(mGalleryItemBackground);
return i;}}
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 digunakan untuk menyimpan daftar item yang akan ditampilkan di dalam
spinner.
<string-array name="planet_array" >
<item>Bumi</item>
<item>Jupiter</item>
<item>Mars</item>
<item>Merkurius</item>
Toast.makeText(getBaseContext(),
"You have selected item : " +
planet[index],
Toast.LENGTH_SHORT).show();
}
@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub
}
});
}
<?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">
<LinearLayout
android:orientation="vertical"
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="fill_parent"
Ini adalah Linear Layout Android sederhana. Tata letak ini menetapkan orientasi vertikal dan
horizontal. Hasil potongan kode di atas adalah sebagai berikut:
Gambar 3.23 Tampilan Linear Layout yang memiliki pengaturan weight dan gravity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="wrap_content"
android:gravity="center"
android:layout_height="wrap_content"
android:text="one"
android:layout_gravity="right"/>
</LinearLayout>
c. 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>
Konten pada Table Layout didefinisikan oleh baris dan tidak berhubungan dengan kolom.
Hal ini mengakibatkan Android menjadi penentu pada pembuatan jumlah kolom. Sebagai
contoh, apabila hendak membuat dua baris dimana baris pertama memiliki dua cell dan baris
kedua memiliki tiga cell, maka Android akan membuat dua baris dan tiga kolom dimana pada
baris pertama memiliki cell yang kosong.
<TableLayout xmlns: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="Cahya"/>
</TableRow>
Meskipun pola Table Layout dengan elemen Table Row sering digunakan,
android.widget.View dapat ditempatkan sebagai turunan di dalam tabel. Sebagai contoh, baris
pertama adalah TextView.
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
EditText mengambil seluruh lebar layar, meskipun belum ditentukan di XML layout. Hal
itu dikarenakan turunan dari Table Layout tidak bisa menentukan
android:layout_width=wrap_content. EditText tersebut dipaksa 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.
<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="wrap_content"
android:layout_height="wrap_content"
android:text="one"
android:padding="40px"/>
</LinearLayout>
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.
<FrameLayoutxmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/frmLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageViewandroid:id="@+id/seamolec"
android:src="@drawable/logo_seamolec"
android:scaleType="fitCenter"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<ImageViewandroid:id="@+id/jarc"
android:src="@drawable/logo_jarc"
android:scaleType="fitCenter"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:visibility="gone"/>
</FrameLayout>
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>
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.
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(). Kemudian, untuk setiap tab, Tabhost.Spec akan dibuat untuk mendefinisikan
g. 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.
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 digunakan untuk widget merupakan turunan dari
android.widget.AdapterView. Class yang meng-extend AdapterView termasuk ListView,
GridView, Spinner dan Gallery. AdapterView sendiri merupakan turunan dari
android.widget.ViewGroup yang berarti bahwa ListView, GridView dan yang lainnya
merupakan container control.
ViewGroup
AdapterView
Tujuan dari Adapter adalah memberikan childview untuk kontainer. Dibutuhkan data dan meta
data tentang pandangan untuk membangun setiap tampilan dari turunannya. Berikut adalah cara
kerja dari SimpleCursorAdapter.
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.
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>
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.
berisi 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 IDsort-
orde. 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. Bentuk lain dari kategori menu seperti sistem menu,
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.
@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 mendefinisikan ID awal untuk sistem menu item ini). Parameter
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
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. Demikian juga untuk mengontrol visibilitas sekelompok menu item dapat
dilakukan dengan menggunakan setGroupVisible. Kemudian ada juga method
setGroupCheckable, 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.
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() return false sehingga normal pemrosesan dapat
berlangsung.
Method onMenuItemClick dipanggil saat menu item telah dipanggil. Kode ini
mengeksekusi ketika item menu diklik, bahkan sebelum menjalankan method
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.
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.
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();
}
Parameter kedua pada method setSingleChoiceItems() adalah nilai integer untuk checked
item, yang menunjukkan posisi item yang dipilih secara default. Gunakan "-1" untuk
menunjukkan bahwa tidak ada item yang dipilih secara default.
Dalam pembuatan progress dialog yang berbentuk bar, langkah yang dilakukan adalah
menentukan parameter pertama sebagai context dari aplikasi, yang kedua adalah judul untuk
dialog, yang ketiga adalah pesan yang ditampilkan dan parameter terakhir adalah apakah
progress tersebut tetap ataukah tidak tetap. Bentuk default dari sebuah progress dialog adalah
sebuah roda berputar. Jika ingin membuat sebuah progress bar yang menunjukkan bar loading,
maka diperlukan sedikit perubahan pada kode, untuk lebih jelas perhatikan kode berikut ini:
ProgressDialog progressDialog;
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMessage("Sedang memuat...");
progressDialog.setCancelable(false);
progressDialog.show();
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;
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");
3.11 Animation
Dalam bab ini, akan dijelaskan bagaimana cara membuat aplikasi agar lebih menarik
dengan memanfaatkan kemampuan untuk menampilkan animasi yang disediakan oleh SDK
Android. Animasi memerlukan banyak kreativitas dari seorang programmer. Animasi adalah
suatu proses dimana sebuah objek pada layar berubah warna, posisi, ukuran, atau orientasi dari
waktu ke waktu. Android mendukung tiga jenis animasi, yaitu:
a. 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.
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
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:
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. Animasi ini juga
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.
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>
<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" />
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);
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