Materi Android Pemula
Dalam kelas ini kita akan belajar tentang komponen-komponen dasar yang digunakan untuk membuat aplikasi android sederhana dengan menggunakan Android Studio. Berikut adalah materi yang akan kita pelajari :
- Pengenalan Android Studio
Android Studio merupakan IDE yag dibuat oleh Jetbrains khusus untuk membuat aplikasi Android. Di dalamnya terdapat fitur yang sangat lengkap untuk membuat proses development menjadi lebih mudah dan cepat. Mulai dari membuat project dengan menggunakan template, mendesain dengan menggunakan Layout Editor, menjalankan aplikasi dengan emulator, sampai membuat APK untuk didistribusikan. - Activity
Merupakan satu komponen yang sangat penting dan berhubungan erat dengan interaksi ke pengguna. Activity menangani tampilan mana yang akan di tampilkan dan mengatur logika yang ada di dalamnya. Activity juga memiliki daur hidup (lifecycle) tersendiri yang dimulai dari onCreate hingga onDestroy. - Intent
Komunikasi antar komponen di dalam sebuah aplikasi merupakan hal yang sangat sering dilakukan. Inilah peran dari suatu Intent. Beberapa fungsi dari Intent adalah digunakan untuk menjalankan sebuah Activity lain dan mengirimkan data saat berpindah antar halaman. - Views dan ViewGroup
Pada dasarnya semua elemen UI (user interface) di aplikasi Android dibangun menggunakan dua buah komponen inti, yaitu View dan Viewgroup. Sebuah View adalah elemen UI tempat kita berinteraksi ketika kita menggunakan aplikasi, seperti tombol, teks, dan gambar. Sedangkan ViewGroup adalah komponen tidak terlihat yang digunakan untuk mengatur tata letak dari komponen yang ada di dalamnya. - Style dan Theme
Prinsip dasar dalam merancang antarmuka aplikasi Android adalah harus mematuhi kaidah yang ditetapkan oleh Design Guideline. Guideline ini dibuat oleh tim Google dengan nama Material Design Component (MDC). Pada modul ini Anda akan mengubah warna tema MDC tersebut dan membuat style untuk komponen yang mirip sehingga membuat proses desain menjadi lebih cepat. - RecyclerView
RecyclerView adalah sebuah komponen tampilan (widget) untuk menampilkan data dengan jumlah banyak secara dinamis. RecyclerView juga memiliki kemampuan untuk menampilkan data secara efisien dalam jumlah yang besar. Ia juga dapat mengatur bagaimana suatu konten ditampilkan dengan menggunakan Layout Manager.
Setelah mempelajari seluruh materi tersebut, Anda dapat membuat sebuah aplikasi Android yang dapat menampilkan banyak informasi seperti berikut.
Keren, bukan? Anda akan diminta untuk mengerjakan submission (tugas akhir) untuk membuat aplikasi seperi di atas. Tentunya dengan tema bebas sesuai keinginan Anda. Mantap!
Prasyarat Kemampuan
Kelas ini merupakan lanjutan dari kelas sebelumnya di learning path Android Developer Dicoding, yakni Memulai Pemrograman dengan Kotlin. Idealnya, Anda telah lulus dari kelas tersebut ya. Jika tidak, maka setidaknya Anda harus memiliki bekal pengetahuan dasar tentang bahasa Kotlin yang mendalam seperti:
- Memahami tentang teori dasar Kotlin. Dengan mempelajari konsep dasar dari Kotlin seperti menggunakan tipe data, membuat fungsi dasar, menangani tipe data null, dan membuat String Template.
- Mempelajari perbedaan antara expression dan statement, cara menggunakan enumeration, cara mengontrol aliran program menggunakan ekspresi if dan when, dan bagaimana menerapkan perulangan menggunakan while, do-while, dan break and continue.
- Mengetahui bagaimana mengelola data di Kotlin dengan menggunakan data class dan collection.
- Memahami konsep function programing dengan mempelajari extension, lambda, higher-order function, recursion serta melihat contoh penerapannya pada colletion operator dan scope function.
- Memahami konsep OOP (Object-Oriented Programming) dengan mempelajari inheritance, abstract class, interface, visibility modifier, dan overloading.
- Mempelajari Coroutine sebagai solusi untuk menjalankan concurrency pada Kotlin.
Sudah siap? Yuk, mari lanjut ke modul selanjutnya!
Mekanisme Belajar
Selamat datang di Dicoding Academy. Sebelum memulai belajar di kelas ini, Anda perlu tahu tahapan dan cara belajar beserta fasilitas yang tersedia agar proses belajar lebih efektif.
Materi Pembelajaran
- Materi Bacaan Elektronik
Materi yang ada dalam kelas ini mayoritas berupa teks atau tulisan. Mengapa demikian? Karena kami menemukan bahwa dalam proses belajar di bidang pemrograman, bentuk materi pembelajaran yang paling efektif untuk diingat, dimengerti, dan yang terpenting, dipraktikkan, adalah dalam bentuk teks. - Forum Diskusi
Setiap kelas memiliki sebuah forum diskusi yang dapat Anda gunakan untuk bertanya (dan menjawab) mengenai materi kelas. Instruktur kami yang terdiri dari Curriculum Developer dan Academy Code Reviewer siap membantu Anda melalui forum diskusi ini.
Tak hanya kami, Anda pun dapat berpartisipasi. Untuk meningkatkan retensi ilmu yang Anda punya, berbagi adalah salah satu kuncinya. Jadi, silakan aktif dan saling membantu di dalam forum.
Jika Anda menemui kendala perihal situs Dicoding dan administrasi kelas, tanyakan kepada kami melalui tombol chat di kanan bawah layar Anda ketika membuka situs Dicoding. Jangan gunakan forum diskusi ya karena itu salah alamat.
Evaluasi Pembelajaran
- Ujian (Kuis, Ujian Akhir Kelas, Knowledge Check)
Terdapat berbagai jenis ujian di kelas guna mengecek pemahaman Anda pada materi pembelajaran. Ketersediaan ujian beserta jenis ujian yang tersedia pada setiap kelas dapat berbeda-beda. Setiap pertanyaan dalam ujian pasti mencakup materi yang telah dibahas. Sehingga jika ada pertanyaan yang tidak dapat Anda jawab, pastikan Anda mengulang kembali pembelajaran.
Forum Diskusi
Ekspektasi
Dengan banyaknya jumlah siswa Dicoding Academy, kami tidak mengharapkan siswa untuk membaca semua diskusi atau komentar pada forum diskusi. Sebaliknya, bacalah hal-hal yang menurut Anda menarik dan dapat membantu Anda dalam menyelesaikan kelas. Lebih baik lagi, jika Anda dapat membantu siswa lainnya dengan memberikan jawaban di bidang yang Anda pahami. Berbagi dalam forum diskusi ini dapat pula membantu meningkatkan retensi ilmu Anda.
Peraturan paling penting adalah bersikap sopan dan memperlakukan semua siswa lain dan instruktur, dengan hormat. Pelanggaran etika ini dapat berakibat pada dikeluarkannya Anda dari kelas.
Anda akan memiliki akses ke forum diskusi kelas selama Anda aktif terdaftar ke kelas ini. Saat masa belajar Anda sudah habis, maka forum diskusi tidak akan dapat diakses. Namun jika Anda sukses menyelesaikan kelas (lulus dan sampai mendapatkan sertifikat kompetensi dari Dicoding), maka Anda tetap dapat mengakses forum diskusi kelas ini walau masa belajar Anda untuk kelas ini telah habis.
Sebelum Memulai Bertanya
- Sebelum membuat diskusi baru, gunakan fitur pencarian untuk cek diskusi lama terlebih dahulu. Problem Anda mungkin pernah dibahas dan dijawab solusinya, dalam forum. Dengan begitu, Anda pun tidak perlu menghabiskan waktu untuk bertanya dan untuk menunggu jawaban kembali.
- Namun jika tidak menemukan diskusi lama dengan topik yang sama dengan masalah Anda, silakan membuat diskusi baru. Simak cara dan langkah berikut ini: https://help.dicoding.com/academy-dicoding/aturan-membuat-pertanyaan-di-forum-diskusi-kelas/.
Fitur Bermanfaat
- Mencari Posting
Anda dapat mencari topik atau diskusi menggunakan tiga cara yang tersedia pada halaman utama forum diskusi.- Gunakan fitur “Cari Judul Diskusi” untuk mencari topik berdasarkan judul atau pertanyaannya.
- Gunakan fitur “Pilih Berdasarkan Modul” untuk melihat diskusi berdasarkan modul kelasnya.
- Gunakan fitur “Keyword Populer” untuk melihat diskusi berdasarkan Keyword yang paling sering ditanyakan.
- Upvote dan Downvote Komentar pada Diskusi
Saat membuka sebuah diskusi, Anda akan menemukan komentar beserta jawaban dari siswa dan instruktur di bagian bawah. Pada setiap komentar terdapat tombol panah atas (˄) dan panah bawah (˅). Klik tombol panah atas (˄) jika Anda merasa komentar atau jawaban tersebut bijaksana, menarik, dan bermanfaat. Gunakan tombol panah bawah (˅) jika Anda merasa komentar atau jawaban tersebut tidak sopan, tidak membantu, atau bahkan tidak tepat.
Gunakan Fitur Upvote dan Downvote ini seperti arahan di atas, sehingga kualitas komentar dan jawaban pada forum diskusi dapat terjaga dengan baik. - Approved Answer
Jika terdapat komentar/tanggapan berupa solusi terbaik dari permasalahan yang Anda tanyakan, maka tandai komentar tersebut sebagai jawaban terpilih. Caranya dengan menekan tombol “Jawaban Terpilih” di sisi kanan atas komentar.
Fitur ini juga akan mempermudah siswa lainnya dengan pertanyaan yang sama untuk menemukan titik terang solusinya.
Mengenal Teman Sekelas Anda
Berhubungan baik dengan teman sekelas dan instruktur merupakan bagian penting dari kelas ini karena mereka dapat membantu jika Anda mengalami kendala dalam pemahaman materi.
Oleh karena itu, kami ingin Anda meluangkan waktu untuk mencairkan suasana dan saling mengenal. Membangun interaksi dengan siswa lain akan membuat pengalaman belajar Anda jauh lebih menyenangkan dan menarik.
Beberapa hal yang dapat Anda tulis pada perkenalan diri:
- Siapa Anda dan dari mana Anda berasal?
- Apa pekerjaan atau pendidikan Anda saat ini?
- Kenapa Anda mengambil pelatihan ini? Apakah mungkin karena Anda sedang mengejar perubahan dalam karir, atau lainnya?
Ayo aktif di forum diskusi kelas ini! Yuk mulai dengan memperkenalkan diri Anda pada thread Perkenalan Diri berikut: |
Glosarium
Ini adalah glosarium dengan istilah umum yang digunakan di dalam kelas. Anda dapat membaca sekilas materi ini untuk mengenali istilah-istilah umum yang ada di modul kelas ini. Selain itu, Anda juga dapat mengunjungi kembali halaman ini setiap kali menemukan istilah yang belum dimengerti. Carilah istilah tersebut pada laman glosarium ini untuk mengidentifikasi makna atau definisinya. Jika masih terdapat kosakata yang tidak Anda pahami dan belum masuk di daftar ini, Anda dapat memberikan saran melalui fitur Laporan Materi.
A
Abstract Class
Sebuah class yang ditandai dengan keyword “abstract”, yang mempunyai beberapa properti dan atau fungsi yang belum terdapat implementasinya. Class ini harus diimplementasi terlebih dahulu oleh class lainnya agar bisa diinisiasi.
Abstraction/Abstraksi
Proses representasi data menjadi lebih umum, dengan menyembunyikan rincian/detail implementasi dan hanya fokus pada yang penting saja.
Annotation
Tanda yang diberikan untuk memasukkan metadata pada suatu class maupun variable pada saat compile time dengan memanfaatkan reflection.
API (Application Programming Interface)
Sebuah interface yang dapat menghubungkan suatu aplikasi dengan aplikasi lainnya, baik dalam satu platform yang sama maupun berbeda.
Architecture
Gambaran umum secara high-level tentang bagaimana suatu aplikasi dibangun.
Argument
Sebuah nilai yang akan disematkan atau diteruskan ke dalam parameter sebuah fungsi.
Asynchronous
Proses yang berjalan tidak berurutan, bersamaan/berbarengan dalam suatu waktu.
Attribute
Merepresentasikan karakteristik dari suatu objek atau properti dari sebuah objek.
B
Best Practice
Suatu cara paling efisien (upaya paling sedikit) dan efektif (hasil terbaik) untuk menyelesaikan suatu tugas, berdasarkan suatu prosedur yang dapat diulangi yang telah terbukti manjur untuk banyak orang dalam jangka waktu yang cukup lama.
Boilerplate Code
Penulisan baris kode berulang di banyak tempat tanpa adanya perubahan.
Bug
Segala bentuk kecacatan dalam suatu aplikasi.
Business Logic/Domain Logic
Kode yang berisi logika utama dari suatu aplikasi yang merepresentasikan proses bisnis di dunia nyata.
C
Callback
Fungsi yang akan diteruskan sebagai argumen ke kode lain yang diharapkan untuk dieksekusi sebagai argumen pada waktu yang tepat.
Class
Class merupakan blueprint atau definisi struktur dari sebuah objek yang belum diinisiasi. Di dalamnya terdapat kumpulan properti dan fungsi yang mencerminkan kegunaan dari class.
Clean Code
Aturan dalam penulisan kode saat pengembangan aplikasi yang digagas oleh Robert C.Martin, di mana menerapkan beberapa teknik tertentu agar kode yang dituliskan bisa dengan mudah dibaca, ditulis, maupun diperbaiki.
Code Isolation
Pemisahan kode berdasarkan fungsinya supaya tidak saling terikat dan mudah dipelihara.
Collection
Objek yang dapat digunakan untuk menyimpan sekumpulan objek.
Compiler
Perangkat lunak yang digunakan untuk menerjemahkan bahasa pemrograman menjadi program system.
Configuration Change
Perubahan konfigurasi yang terjadi pada device yang menyebabkan Activity di-destroy/dihapus dari memori lalu dibuat lagi dari awal, misalnya saat screen rotation (perubahan orientasi layar dari potrait ke landscape dan sebaliknya).
Constant (Konstanta)
Tidak berubah-ubah nilainya.
Constructor
Method yang secara default sudah terbentuk ketika kelas dibuat. Ketika suatu kelas dibuat (instansiasi) maka konstruktor akan terpanggil juga.
Console
Tool yang dapat digunakan untuk menjalankan perintah atau melihat pesan log.
Converter
Aplikasi yang berfungsi untuk mengubah suatu data dari satu data ke bentuk data lainnya.
Coupling
Ukuran kuatnya keterikatan/ketergantungan antara suatu modul dengan modul lainnya. Sehingga apabila suatu modul diubah, modul lain juga harus diubah.
Crash
Keadaan dari suatu sistem (aplikasi atau sistem operasi), di mana sistem tersebut tidak berfungsi dengan normal dan terpaksa mengakhiri berjalannya sistem tersebut.
D
Data Classes
Kelas sederhana yang bisa berperan sebagai data container pada kotlin. Di dalamnya terdapat beberapa fungsi yang sudah disediakan untuk menghandle beberapa operasi data seperti equals(), toString(), hashCode(), & copy().
Debug
Proses mengidentifikasi atau menghapus error pada sebuah perangkat keras atau perangkat lunak.
Dependency
Dalam Android, ini biasanya merujuk pada library tambahan atau komponen yang dibutuhkan oleh aplikasi untuk dapat melakukan fungsi tertentu yang tidak bisa dilakukan secara fedault.
Design Pattern
Pola dasar atau template dari sebuah cara untuk menyelesaikan suatu permasalahan dalam situasi yang berbeda-beda.
E
Encapsulation
Konsep fundamental dalam pemrograman berbasis objek yang membungkus data dengan beberapa method/fungsi yang mengelola data, dan membatasi akses data secara langsung dari luar unit (class).
Endpoint
Bagian akhir pada API yang digunakan untuk menentukan data apa yang diambil.
Enum
Fitur yang bisa digunakan untuk menyimpan kumpulan objek yang telah didefinisikan menjadi tipe data konstanta.
Exception
Kesalahan yang muncul saat aplikasi dijalankan.
Expression
Kombinasi dari data, variabel, dan atau operator yang mengembalikan suatu nilai.
Extends
Kata kunci yang digunakan untuk mengimplementasikan konsep inheritance.
F
Field
Bagian dari class yang berisi nilai khusus untuk object.
Filter
Proses penyaringan terhadap sebuah kumpulan object.
Framework
Kerangka kerja yang sudah disediakan untuk mengembangkan aplikasi. Kerangka kerja di sini sangat membantu developer dalam menuliskan sebuah kode dengan lebih terstruktur dan tersusun rapi.
G
Generic
Menggambarkan karakteristik (gambaran umum) dari sebuah jenis atau kelompok tetapi tidak spesifik.
Getter
Fungsi yang digunakan untuk membaca nilai sebuah variabel yang terenkapsulasi.
I
Immutable
Objek yang nilainya tidak bisa diubah saat runtime.
Implementation
Realisasi dari suatu spesifikasi aplikasi, misalnya seperti mengimplementasikan interface atau membuat real class dari abstract class.
Index
Indikator dalam bentuk angka yang merepresentasikan posisi dari sebuah item di dalam sebuah list atau daftar (daftar karakter, array, dsb).
Inisialisasi
Sebuah proses pemberian nilai awal setelah deklarasi sebuah variabel.
Inner Class
Kelas yang dideklarasikan di dalam sebuah kelas.
Instance
Perwujudan dari sebuah class (kelas).
Interface
Kontrak yang digunakan untuk berkomunikasi antara satu pihak dengan pihak yang lain. Di mana semua method di dalamnya harus diimplementasikan oleh class yang memakainya (mengimplementasikannya)
J
JSON (JavaScript Object Notation)
Format data yang menyajikan pasangan key dan value yang digunakan dalam pertukaran data antar program aplikasi dan juga bisa digunakan sebagai tempat penyimpanan dari suatu data.
K
Keyword
Dalam pemrograman, keyword adalah susunan huruf atau frasa yang sudah disediakan oleh bahasa program tertentu dan mempunyai arti spesial pada compiler.
L
Lifecycle
Siklus hidup atau tahapan-tahapan suatu proses dalam aplikasi mulai dari awal sampai akhir.
M
Mapping
Proses perubahan dari satu jenis model data ke jenis model lainnya.
Method
Bagian dari class yang menjalankan suatu aksi tertentu.
Mutable
Tipe variable yang bisa diubah nilainya.
N
Native
Asli atau murni.
Networking
Proses untuk mengambil data dari network/server.
Null
Tidak memiliki nilai/value.
Nullable
Kondisi dari sebuah variabel yang dapat menampung nilai null.
O
Object/Objek
Merupakan instance atau wujud nyata dari suatu kelas.
Observable
Objek yang bisa diamati/di-observe dalam jangka waktu tertentu.
Operator
Fungsi tertentu yang digunakan untuk menjalankan sebuah proses untuk menentukan hasil.
Override
Kata kunci yang digunakan untuk mengambil alih fungsi yang diwariskan.
P
Package
Cara yang digunakan untuk mengelompokkan kumpulan kelas.
Parameter
Nilai inputan berupa variabel pada saat fungsi itu didefinisikan.
Parenthesis
Tanda kurung/( ) yang berada pada sebuah function atau constructor.
Parsing
Proses penguraian suatu data dari satu data ke bentuk data lainnya.
Plugins
Kode dengan fungsi tertentu yang memungkinkan aplikasi atau program untuk menjalankan fitur tambahan di aplikasi atau program tersebut.
Properties
Atribut yang menjadi anggota dari suatu kelas. Properti digunakan untuk menyimpan data yang relevan dengan kelas. Seperti yang sudah disebutkan sebelumnya seperti tinggi, berat, dan umur adalah properti dari suatu kelas.
Q
Query
Syntax atau perintah yang dipakai untuk mengakses dan menampilkan data pada sistem database SQL.
R
Read-Only
Adalah kondisi di mana kita hanya dapat menjalankan proses membaca namun tidak dapat menjalankan proses menulis.
Refactor
Proses menulis ulang suatu kode menjadi lebih baik.
Reference
Suatu value yang mempunyai akses secara tidak langsung ke data atau objek lain.
Reliability
Probabilitas konsistensi suatu komponen atau sistem untuk melakukan fungsi yang ditentukan dalam periode waktu tertentu di bawah kondisi yang dirancang untuk beroperasi.
Return Type
Tipe kembalian dari sebuah function.
S
Statement
Sebuah instruksi dalam bentuk kode yang digunakan oleh komputer untuk menjalankan aksi tertentu.
T
Thread
Sekumpulan instruksi yang dapat dijalankan pada CPU.
Tipe Data Primitif
Tipe data primitif adalah tipe data yang hanya menyimpan satu nilai pada setiap satu variabel, seperti integer, string, dan boolean.
V
Variable
Dalam konteks pemrograman, variable adalah tempat yang digunakan untuk menyimpan suatu data.
Visibility Modifier
Keyword yang mengatur aksesibilitas dari suatu class, objek, interface, fungsi, dan properti. Contohnya seperti public, private, protected, dan internal.
Daftar Referensi
[1] Android Developers Channel. “Google Keynote (Google I/O ‘21)”. youtube.com. https://youtu.be/XFFrahd05OM (diakses pada 20 Mei 2021).
[2] Statista. “Mobile operating systems' market share worldwide from January 2012 to January 2021”. statista.com. https://www.statista.com/statistics/272698/global-market-share-held-by-mobile-operating-systems-since-2009/ (diakses pada 11 Apr 2021).
[3] Statista. “Number of available applications in the Google Play Store from December 2009 to December 2020”. statista.com. https://www.statista.com/statistics/266210/number-of-available-applications-in-the-google-play-store/ (diakses pada 11 Apr 2021).
[4] M. Shafirov. “Kotlin on Android. Now official”. blog.jetbrains.com. https://blog.jetbrains.com/kotlin/2017/05/kotlin-on-android-now-official/ (diakses pada 11 Apr 2021).
[5] X. Ducrohet; T. Norbye; K.Chou. “Android Studio: An IDE built for Android”. android-developers.googleblog.com. https://android-developers.googleblog.com/2013/05/android-studio-ide-built-for-android.html (diakses pada 12 Apr 2021).
Pengenalan Android
Apa itu Android
Android adalah sistem operasi yang dikeluarkan oleh Google. Android dibuat khusus untuk smartphone dan tablet. Berbagai macam produsen telah menggunakan Android sebagai sistem operasi untuk peranti (device) yang mereka produksi. Android juga mempunyai store dengan lebih dari 2.5 miliar pengguna aktif per bulannya, per Mei 2019 [1].
Mengapa Android
Kenapa menggunakan Android? Android memanjakan penggunanya dengan fitur yang sangat canggih dan tampilan yang bagus. Sistem Android dapat digunakan sebagai alat multimedia seperti pemutar musik dan video. Ia juga memiliki perangkat keras seperti accelerometer, gyroscope dan sensor lainnya.
Di samping itu ada beberapa hal yang membuat Android menjadi sistem operasi yang memang layak digunakan oleh pengguna atau dikembangkan para developer, seperti yang akan diuraikan berikut ini.
Sistem Operasi Smartphone Terpopuler
Pada tahun 2013, Android menjadi operation system (OS) terlaris pada tablet dan smartphone. Kini market share Android sedikitnya 70 % dari total penjualan smartphone di tingkat global (statista.com) [2]. Tercatat pada tahun 2016 Android store memiliki lebih dari 2.8 juta aplikasi [3].
Android menarik bagi perusahaan teknologi yang membutuhkan barang siap jadi, biaya rendah dan kustomisasi OS untuk perangkat teknologi tinggi mereka. Hal ini menjadi daya tarik bagi banyak perusahaan, sehingga mereka memilih Android.
Source code dari Android bersifat open source. Ini adalah hal menarik bagi komunitas developer, karena lisensi open source sangat mendukung untuk mengembangkan produknya dengan aman.
Store
Aplikasi Android bisa didistribusikan menggunakan web, copy APK, dan store. Android store , yaitu Google Play, merupakan cara termudah bagi para developer untuk mendistribusikan aplikasinya ke pasar dengan miliaran pengguna.
Google play merupakan store resmi Android yang dikelola oleh Google. Pengguna bisa mencari dan mengunduh aplikasi yang dikembangkan dengan menggunakan Android Software Development Kit. Google Play tak hanya menawarkan aplikasi. Ada beragam konten lainnya yang dapat dinikmati pengguna, misalnya media digital, musik, buku, majalah, film dan program televisi.
Bagaimana para developer memonetisasi aplikasi yang ada di dalam Google Play? Strategi monetisasi aplikasi yang ditawarkan Google Play ada bermacam-macam. Dimulai dari app berbayar (paid distribution), pembelian dalam aplikasi (in-app purchase), langganan (subscriptions), dan iklan (ads). Tentunya developer harus mengikuti aturan yang ada untuk memastikan bahwa pengguna mendapatkan pengalaman (user experience) terbaik.
Development Kit untuk Developer
Android Software Development Kit (SDK) merupakan kit yang bisa digunakan oleh para developer untuk mengembangkan aplikasi berbasis Android. Di dalamnya, terdapat beberapa tools seperti debugger, software libraries, emulator, dokumentasi, sample code dan tutorial.
Bahasa pemrograman yang sering digunakan untuk mengembangkan aplikasi Android adalah Java. Namun ada beberapa bahasa lainnya yang dapat digunakan, seperti C++ dan Go. Pada IO 2017 Google juga menetapkan Kotlin sebagai tambahan bahasa resmi [4].
Berbicara tentang pemrograman tentunya tak lepas dari Integrated Development Environment (IDE). Pada 2014 Google mengeluarkan IDE yang bernama Android Studio yang berbasiskan Intellij IDEA.
Dengan menggunakan Android Studio, para developer dapat membuat aplikasi dari nol hingga dipublikasikan ke dalam store. Android Studio juga mempunyai beberapa fitur built-in yang sangat membantu para developer untuk memaksimalkan proses pembuatan aplikasi. Fitur-fitur ini misalnya project template, layout editor, debugging, testing, hingga membuat berkas APK.
Sejarah Perkembangan Android
Berikut adalah rangkaian sejarah perkembangan Android yang resmi diluncurkan oleh Google dari waktu ke waktu.
Platform Version | Version Code | Release date | API level | Feature Highlight | Icon |
---|---|---|---|---|---|
13 | TIRAMISU | August 15, 2022 | 33 |
| ![]() |
12 | S | October 4, 2021 | 31-32 |
| ![]() |
11 | R | September 8, 2020 | 30 |
| ![]() |
10 | Q | September 3, 2019 | 29 |
| ![]() |
9 | P | August 6, 2018 | 28 |
| |
8.0-8.1 | O | October 25, 2017 | 26 - 27 |
| |
7.1 - 7.1.2 | N | August 22, 2016 | 24 - 25 |
| |
6.0 - 6.0.1 | M | October 5, 2015 | 23 |
| ![]() |
5.1 - 5.1.1 | LOLLIPOP | November 12, 2014 | 21 - 22 |
| |
4.4 - 4.4.4 | KITKAT | October 31, 2013 | 19 - 20 |
| |
4.1 - 4.3.1 | JELLY_BEAN | July 9, 2012 | 16-18 |
| |
4.0 - 4.6 | ICE_CREAM_SANDWICH | October 19, 2011 | 14-15 |
| ![]() |
3.0 - 3.2.6 | HONEYCOMB | February 22, 2011 | 11 - 13 |
| ![]() |
2.3 - 2.3.7 | GINGERBREAD | February 9, 2011 | 9 - 10 |
| |
2.2 - 2.23 | FROYO | May 20, 2010 | 8 |
| ![]() |
2.0 - 2.1 | ECLAIR | October 26, 2009 | 5-7 |
| |
1.6 | DONUT | September 15, 2009 | 4 |
| ![]() |
1.5 | CUPCAKE | April 27, 2009 | 3 | - |
Saat versi baru Android dirilis, developer hendaknya terus mengikuti best-practice terbaru untuk memastikan aplikasi yang dibuat tetap memberikan pengalaman yang terbaik di sebanyak mungkin device. Untuk mencari tahu tentang versi terbaru, Anda dapat melihatnya pada tautan berikut.
ART dan DVM
Dari tabel sejarah perkembangan di atas dapat kita lihat ada kolom DVM / ART. Kolom ini menunjukkan eksekusi kompilasi ketika menjalankan aplikasi Android. Pada API KitKat dan sebelumnya Android menggunakan DVM (Dalvik Virtual Machine). DVM menerapkan pendekatan JIT (Just-In-Time), di mana kompilasi dijalankan ketika ada permintaan untuk menjalankan aplikasi. Sedangkan ART (Android Runtime) menerapkan pendekatan berbeda yaitu AOT (Ahead-Of-Time). AOT melakukan kompilasi pada saat proses instalasi aplikasi.
Dari versi Lollipop hingga sekarang, Android sepenuhnya mengadopsi ART. Mengapa demikian? DVM menggunakan JIT yang berarti kompilasi dilakukan setiap kali aplikasi dijalankan. Hal ini sangat mempengaruhi kecepatan respon aplikasi. Setiap kali kita menyentuh ikon aplikasi maka kompilasi akan dilakukan. Tentu proses ini menghabiskan CPU dan berimbas pada relatif lebih borosnya penggunaan baterai.
Beda dengan DVM, ART melakukan proses kompilasi pada saat proses instalasi. Jadi setiap kali aplikasi dijalankan, sudah tidak ada lagi proses kompilasi. Hal ini meningkatkan performa dalam menjalankan aplikasi. Selain itu karena penggunaan sumber daya CPU bisa dikurangi, pemakaian baterai jadi lebih hemat. Akan tetapi ART membutuhkan space (ukuran berkas) yang lebih besar jika dibandingkan dengan DVM.
Jika ingin mendalami proses run-time yang ada di Android, silakan klik tautan berikut ini:
Beberapa bacaan dasar yang dapat menambah wawasan Anda, antara lain:
Android Studio
Android Studio adalah Lingkungan Pengembangan Terpadu - Integrated Development Environment (IDE) untuk pengembangan aplikasi Android, berdasarkan IntelliJ IDEA . Selain merupakan editor kode IntelliJ dan alat pengembang yang berdaya guna, Android Studio menawarkan fitur lebih demi meningkatkan produktifitas Anda saat membuat aplikasi Android, misalnya:
- Template: template memulai project maupun Activity tanpa harus membuatnya dari nol.
- Intelligent code editor: code completion yang memudahkan untuk menulis kode dengan cepat tanpa harus menuliskan secara lengkap. Selain itu, juga ada warning apabila terdapat kesalahan penulisan kode.
- Design tool: digunakan untuk mendesain aplikasi beserta melihat preview secara langsung sebelum dijalankan.
- Flexible build system: Android Studio menggunakan Gradle yang fleksibel untuk menciptakan build variant yang berbeda untuk berbagai device. Anda juga dapat menganalisa prosesnya secara mendetail.
- Emulator: menjalankan aplikasi tanpa harus menggunakan device Android.
- Debugging: memudahkan untuk mencari tahu masalah.
- Testing: menjalankan pengujian untuk memastikan semua kode aman sebelum rilis.
- Publish: membuat berkas AAB/APK dan menganalisanya guna dibagikan dan di-publish ke PlayStore. Dilengkapi dengan Instant Run untuk melihat perubahan tanpa harus build project dari awal.
- Integrasi: Terhubung dengan berbagai layanan yang memudahkan untuk mengembangkan aplikasi, seperti Github, Firebase, dan Google Cloud.
Persyaratan Sistem
Windows | Mac |
---|---|
|
|
Linux | Chrome OS |
---|---|
|
Perangkat yang direkomendasikan bisa dilihat di chromeos.dev. |
Persiapan Tools
JDK
Salah satu Bahasa yang bisa digunakan untuk development Android adalah Java. Selain Java ada beberapa Bahasa lain yang bisa digunakan seperti C/C++, Go, dan Kotlin (per Mei 2017).
Pada akademi ini kita hanya akan fokus menggunakan Kotlin dan Java sebagai bahasa pemrograman. Oleh karena itu mari instal dulu software yang harus kita gunakan untuk coding (menuliskan baris code). Siapkan senjata Anda sebelum berperang.
Instal Java Development Kit yang bisa kita dapatkan pada tautan berikut:
Biasanya muncul pertanyaan, "Apakah JRE cukup?" Tidak, JRE adalah Java Runtime Environment yang berfungsi sebagai Virtual Machine untuk menjalankan program Java. Sedangkan JDK merupakan Java SE Development Kit, di mana JRE juga terdapat di dalamnya. Dan yang lebih penting adalah di dalamnya terdapat compiler dan tools untuk membuat dan compile program. Sederhananya JRE untuk menjalankan program, sedangkan JDK untuk membuat program.
Catatan:
Saat ini ketika menginstall Android Studio sudah terdapat JDK yang bawaan (OpenJDK) yang bisa digunakan. Sehingga langkah di bawah ini bersifat opsional jika Anda mengalami kendala JDK.
Mari kita mulai dengan proses instalasi dari JDK dari Oracle.
- Langsung saja buka tautan di atas menggunakan browser Anda. Pilihlah link download yang sesuai dengan OS yang Anda pakai.
Jangan lupa untuk mencentang Accept License Agreement dan klik tombol Download.
Anda akan diminta untuk login terlebih dahulu, silakan mendaftar dulu jika Anda belum memiliki akun.
Setelah proses mengunduh selesai, langsung install ke gawai Anda dan ikuti petunjuknya sampai selesai.
Android Studio
Pada akademi kali ini kita akan menggunakan Android Studio sebagai IDE (Integrated Development Environment). Android Studio dirilis 16 Mei 2013 saat Google IO berlangsung [5]. Android Studio berbasiskan JetBrains Intellij IDEA, dan dikhususkan untuk pengembangan software berbasis Android.
Mari langsung saja kita mulai instalasi Android Studio.
- Buka web browser dan masuk ke halaman https://developer.android.com/studio. Tautan tersebut akan otomatis mengarahkan ke versi software yang sesuai dengan OS Anda. Anda juga dapat melihat fitur fitur baru dan fitur utama pada halaman tersebut.
- Klik tombol Download Android Studio.
- Baca license agreement dan beri tanda centang pada I have read and agree with the above terms and conditions yang ada di bagian bawah.
- Klik Download Android Studio ... for ... . Pilih lokasi penyimpanan dan tunggu proses mengunduh sampai selesai.
Kemudian instal Android Studio ke komputer Anda dan ikuti petunjuknya sampai selesai. Untuk melihat proses instalasi secara lebih detail untuk masing-masing OS, Anda dapat melihatnya pada tautan berikut.
Saat proses instalasi, Android Studio juga akan menginstal beberapa komponen lain supaya Android Studio dapat berjalan lancar. Contohnya adalah ADB dan SDK. Android SDK adalah sekumpulan tool yang digunakan untuk mengembangkan aplikasi Android. Untuk itu, silakan izinkan atau tekan "Yes" jika ada pop up atau alert yang muncul dan pastikan PC Anda sudah terhubung ke internet saat proses instalasi tersebut.
Setelah selesai melakukan instalasi Android Studio, akan muncul seperti gambar di bawah ini.
Gambar di atas berarti aplikasi Android Studio sudah bisa digunakan.
Anda juga dapat melihat semua versi dari Android Studio yang dapat Anda unduh pada tautan ini:
Catatan: Untuk migrasi dari Android Studio versi 2.x ke versi 3.4 ke atas, terkadang perlu menyesuaikan beberapa kode terutama pada berkas gradle-nya. Silakan kunjungi tautan ini untuk keterangan lebih lanjut.
Pengenalan Project pada Android Studio
Supaya lancar ketika menggunakan Android Studio, sebaiknya Anda perlu mengetahui strukturnya terlebih dahulu. Jika terbiasa menggunakan produk IntelliJ IDEA lainnya, akan mudah bagi Anda untuk menavigasi tata letak dan struktur Android Studio. Hanya saja perbedaannya terletak pada komponen tambahan pendukung yang membantu pengembangan dan pembuatan aplikasi Android.
Yuk, kita mulai mengenal Android Studio lebih jauh.
Project Android Pertama
Kali pertama menjalankan Android Studio, Anda akan melihat tampilan seperti berikut ini.
Untuk memulai proyek baru, pilihlah “New project”.
Jika sudah membuka project lain, klik File → New → New Project untuk membuat project baru.
Project Wizard
Selanjutnya, mari kita membuat sebuah aplikasi pertama, yaitu Hello World. Ikuti langkah-langkahnya di bawah ini.
- Setelah memilih New project, Anda diminta untuk memilih tema template awal project. Adanya template mempermudah Anda supaya tidak membuat project dari nol, sehingga proses awal menjadi lebih cepat dan sesuai dengan best-practice tanpa error (misal tidak mendaftarkan Activity ke Manifest).
Saat ini Android Studio sudah menyediakan berbagai macam template activity dari yang paling sederhana hingga yang paling kompleks seperti:
Selain itu, Anda juga bisa memilih target device mana yang akan dibuat seperti Phone and Tablet, Wear OS, TV, Android Auto atau Android Things.Nama Template Activity Fungsi No Activity Project murni tanpa ada Activity yang ditambahkan Basic Activity Activity dengan template komponen material design seperti FloatingActionButton dan menu Toolbar Bottom Navigation Activity Activity dengan tampilan bottom navigation menu di bagian bawah Empty Activity Activity dalam bentuk yang paling sederhana (tanpa menu) Fullscreen Activity Activity fullscreen tanpa status bar Google AdMob Ads Activity Activity dengan konfigurasi default iklan Admob Google Maps Activity Activity dengan menyediakan konfigurasi dasar Google Maps Login Activity Activity untuk halaman login Master/Detail Flow Activity yang diperuntukan untuk alur aplikasi master detail pada peranti tablet Navigation Drawer Activity Activity dengan tampilan side bar menu yang bisa di-swipe Settings Activity Activity yang diperuntukan untuk konfigurasi aplikasi Scrolling Activity Activity dengan kemampuan scroll konten didalamnya secara vertikal Tabbed Activity Activity yang diperuntukan untuk menampilkan lebih dari satu tampilan dengan menggunakan Tab dan dapat digeser ke kanan dan ke kiri (swipe) dengan menggunakan komponen ViewPager Fragment + ViewModel Activity dengan menerapkan Fragment & ViewModel
Kemudian Anda akan diarahkan ke dalam dialog untuk memberi nama dari aplikasi, lokasi proyek dan nama package seperti berikut.
Berikut adalah fungsi dari masing-masing kolom di atas.- Name: nama dari aplikasi yang akan tampil di Toolbar.
- Package name: digunakan sebagai identifikasi unik dari aplikasi ketika sudah di-publish di PlayStore. Antara satu aplikasi dengan aplikasi lainnya harus berbeda. Biasanya penamaan package menggunakan format domain, tetapi urutannya dibalik.
- Save location: mengganti direktori tempat kita menyimpan proyek.
- Language: memilih bahasa yang digunakan untuk mengembangkan aplikasi, apakah menggunakan Kotlin atau Java.
- Minimum SDK: menentukan versi minimum Android yang dapat menjalankan project ini. Anda dapat menekan Help me choose untuk melihat distribusi pemakai Android pada setiap versi sehingga bisa menentukan minimum SDK yang cocok.
Antarmuka Android Studio
Setelah membuat proyek pertama di Project Wizard, Anda akan dihadapkan pada tampilan penuh Android Studio berbasis IntelliJ IDEA seperti di bawah ini.
Mungkin tampilan tersebut akan berbeda dengan yang ada di layar Anda karena perbedaan konfigurasi dan versi Android Studio. Untuk meningkatkan produktivitas, mari kita bahas lebih jauh tentang antarmuka (interface) yang ada di Android Studio ini.
Toolbar
Merupakan tool yang sering digunakan dalam development, mulai dari copy/paste, build, menjalankan aplikasi, hingga menjalankan emulator.
Navigation Bar
Membantu untuk melihat struktur dari kedalaman (depth) dan posisi proyek yang saat ini sedang dibuka.
Project Explorer dan Editor
Merupakan bagian utama dari IDE Android Studio karena di sanalah tempat kita menulis kode nantinya. Pada tampilan di atas, sebelah kiri adalah struktur proyek dan sebelah kanan adalah editor. Bagian ini akan dibahas lebih detail di poin selanjutnya.
Tool Window Bar
Tools menu yang mengelilingi editor ini (baik di kiri, kanan, maupun bawah) merupakan tool yang dapat diatur lebarnya dan ditampilkan secara terpisaj.
Status Bar
Terletak di bagian paling bawah dalam Android Studio, ia berfungsi untuk menampilkan status proyek dan pesan peringatan (warning message) bila ada.
Struktur Proyek
Setiap proyek di Android Studio berisi satu atau beberapa modul dengan berkas kode sumber dan berkas sumber daya. Jenis-jenis modul mencakup:
- Modul Aplikasi Android,
- Modul Pustaka, dan
- Modul Google App Engine.
Secara default, Android Studio akan menampilkan berkas proyek Anda dalam tampilan proyek Android, seperti yang ditampilkan dalam gambar berikut:
Tampilan disusun berdasarkan modul untuk memberikan akses cepat ke berkas sumber utama proyek Anda.
Secara default ketika kita membuat proyek baru, Android Studio akan menampilkan struktur yang lebih ringkas dan cepat sesuai dengan kebutuhan pengembangan Android. Bila ingin melihat struktur proyek dalam bentuk selain standar Android, kita dapat mengubahnya dengan tombol dropdown yang terdapat di atas project structure.
Pada bagian ini kita dapat mengganti tampilan project structure sesuai kebutuhan.
Mari kita bahas lebih detail tentang proyek yang baru saja kita buat. Berikut adalah isi dari masing-masing folder yang ada pada struktur project.
Android Manifest
AnndroidManifest adalah salah satu berkas yang harus ada di dalam sebuah proyek Android. Manifest memberikan beragam informasi penting kepada sistem Android. Sistem perlu mengetahui apa yang akan digunakan oleh aplikasi sebelum dijalankan.
Beberapa fungsi yang ada di dalam Android Manifest adalah sebagai berikut:
- Komponen Aplikasi
Berfungsi untuk mendeskripsikan komponen dasar aplikasi Android, mulai dari activity, services, broadcast receiver, dan content provider.<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyIntentService" android:exported="false" /> <receiver android:name=".MyReceiver" android:enabled="true" android:exported="true"></receiver> </application>
Komponen aplikasi semuanya berada di antara tag <application>. Ia juga berfungsi sebagai penamaan kelas yang mengimplementasi komponen dan mendeskripsikan kemampuannya seperti intent-filter, di mana fungsinya mendeskripsikan bahwa komponen itu adalah yang pertama kali dijalankan.
- Permission
Mendeklarasikan permission apa saja yang harus dimiliki oleh aplikasi untuk akses ke dalam komponen API seperti internet, external storage, contact, lokasi, dan lain sebagainya. Sebagai contoh ini adalah kode untuk permission Internet<uses-permission android:name="android.permission.INTERNET"/>
Kode ini biasanya diletakkan di atas tag <application> dan masih di dalam tag <manifest>
Java
Merupakan salah satu folder yang sering dipakai, berisi berkas source code kita yang ditulis dalam bahasa Kotlin/Java, termasuk juga kode Unit Test dan androidTest (Instrumentation Test).
Catatan:
Penamaan folder "java" bisa juga diganti sesuai dengan bahasa yang dipakai, misal "kotlin."
Res / Resource
Mengatur resource di dalamnya, yang mana bukan berupa kode, melainkan layout aplikasi, sumber gambar, ikon, hingga style. Di dalam folder res ini juga terdapat sejumlah folder yang sudah diatur dan dikategorikan sesuai kebutuhan, seperti:
- Drawable
Untuk menyimpan berkas gambar maupun ikon. - Layout
Salah satu folder yang sering dipakai untuk berkas desain aplikasi. - Mipmap
Untuk menyimpan logo dalam berbagai dimensi. - Values
Berisi berbagai macam sumber data, seperti colors.xml untuk warna, strings.xml untuk teks, dimens.xml untuk ukuran, dan themes.xml untuk membuat theme dan style.
Selain itu, juga ada jenis folder resource yang bisa Anda tambahkan seperti yang ada pada tautan berikut.
Gradle
Gradle merupakan open source build automation system. Automation system berguna untuk mengotomatisasi proses pembuatan dari software build dan proses-proses terkait lainnya termasuk compile source code menjadi binary code, packaging binary code, dan menjalankan automated test.
build.gradle (Project: MyApplication)
Merupakan software build tingkat teratas yang meliputi keseluruhan dari proyek dari sebuah aplikasi. Di dalamnya berisi konfigurasi library Android dan Kotlin untuk semua module.
build.gradle (Module: app)
Merupakan software build yang ada pada setiap modul di dalam proyek sebuah aplikasi. Beberapa konfigurasi yang diedit di antaranya adalah android settings, defaultConfig dan productFlavors, buildTypes, dan dependencies.
plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { namespace 'com.dicoding.picodiploma.myapplication' compileSdk ... defaultConfig { applicationId "com.dicoding.picodiploma.myapplication" minSdkVersion ... targetSdkVersion ... versionCode 1 //incremental versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation ... testImplementation ... androidTestImplementation ... }
Berikut adalah beberapa detail konfigurasi yang dapat diubah pada level modul.
- namespace: package name unik yang digunakan untuk Play Store, sama seperti yang kita atur pada saat membuat project.
- compileSdk: merupakan versi SDK yang digunakan untuk meng-compile project.
- applicationId: biasanya sama dengan namespace, nilainya bisa berubah untuk kebutuhan build variant.
- minSdk: merupakan versi SDK minimal yang didukung oleh project ini. Android dengan versi di bawahnya tidak dapat menjalankan aplikasi ini.
- targetSdk: target versi SDK yang menandakan aplikasi ini sudah dites pada versi SDK tertentu. Best practice-nya adalah memilih SDK yang terbaru. Jika tidak didefinisikan, nilainya sama dengan minSdk.
- versionCode: nilai integer yang menandakan versi dari aplikasi. Apabila kita sudah publish aplikasi ke PlayStore dengan versionCode 1, ketika ingin meng-update aplikasinya lagi ke Playstore, kita perlu mengubah versionCode menjadi 2 (incremental satu tingkat). Jika tidak diubah, PlayStore akan menolak APK yang di-upload.
- versionName: versi aplikasi berupa String yang biasa ditunjukkan ke user, misalnya 1.0.1.
- buildTypes: di dalamnya terdapat properties dari debuggable, ProGuard enabling, debug signing, version name suffix dan test information.
- dependencies: di dalamnya terdapat informasi tentang library yang digunakan oleh aplikasi.
Untuk lebih mengenal Android Studio lebih dalam silakan baca materi ini https://developer.android.com/studio/intro/index.html.
Sync Project
Setiap kali terjadi perubahan informasi di dalam build.gradle kita harus melakukan sinkronisasi terlebih dahulu. Tombol sync now akan muncul pada sebelah kanan atas ketika terjadi perubahan.Setelah proses sinkronisasi selesai, log akan menampilkan informasi apakah proses sinkronisasi berhasil atau tidak.
Resource Manager

Resource Manager berfungsi untuk memanajemen segala resource yang ada di proyek Anda seperti gambar, warna, layout dll. Jika Anda perhatikan struktur dari res, dengan menggunakan Resource Manager semua resource akan tampil di sini dan dapat dimanipulasi sesuai kebutuhan.
Useful Tools pada Android Studio
Android Studio menyediakan fasilitas yang powerful di bawah IntelliJ IDEA ini. Banyak tools milik Android yang membantu kita saat mengembangkan Aplikasi. Mari kita bahas tools yang sering digunakan beserta manfaatnya.
Shortcut
Pencarian:
- Shift+Shift
Search Everywhere, atau dapat dikatakan pencarian semua jenis berkas yang masih dalam 1 proyek. - Ctrl+F
Find, pencarian teks dalam salah satu berkas. - Ctrl+Shift+F
Find in path, pencarian teks di seluruh berkas proyek. - Ctrl+Shift+A
Find action, pencarian aksi atau perintah-perintah yang ada di Android Studio. - Ctrl+R
Replace, mengganti teks di dalam berkas.
Navigasi:
- Ctrl+N
Find Class, navigasi ke kelas tertentu. - Ctrl+Shift+N
Find file, navigasi ke berkas. - Ctrl+B
Go to declaration, lompat ke deklarasi yang dipilih. - Alt+↑
Lompat ke method sebelumnya. - Alt+↓
Lompat ke method sesudahnya. - Ctrl+G
Go to line, lompat ke baris tertentu. - Ctrl+E
Membuka berkas teranyar (recent file). - Ctrl+Left Mouse (or) Ctrl+Alt+F7
Melihat penggunaan pada variabel/objek yang diklik. - Alt+F7 / Ctrl+F7
Melihat penggunaan variabel/objek yang dipilih di seluruh berkas proyek. - Ctrl+Shift+B
Mencari tahu implementasi dari variabel/objek yang dipilih.
Redaksi:
- Ctrl+D
Menggandakan bagian yang dipilih. - Ctrl+Q
Melihat dokumentasi dengan tampilan minimal. - Ctrl+P
Melihat isi dari parameter, penting ketika melihat method dari Android atau library lain. - Ctrl+Space
Basic code completion, menampilkan saran untuk melengkapi kode Anda. - Ctrl+Shift+Space
Smart code completion, menampilkan saran kode untuk melengkapi kode Anda dengan lebih pintar (menampilkan apa yang benar-benar terkait dengan kode Anda). - Alt+Insert
Generate code, menghasilkan (generate) kode. Perintah ini sangat memudahkan ketika membuat constructor dan setter/getter. - Ctrl+Alt+L
Memformat ulang kode, merapikan kode. - Ctrl+Y
Delete One Line, menghapus satu baris kode. - Ctrl+Alt+V
Create variable, membuat teks yang diblok menjadi sebuah variabel. - Ctrl+Alt+M
Create method, membuat teks yang diblok menjadi sebuah fungsi. - Shift+F6
Rename, untuk mengganti nama suatu file atau variabel maupun fungsi.
Run:
- Ctrl+F9
Make project, build project. - Ctrl+Shift+F9
Melakukan kompilasi pada berkas, package atau modul. - Shift+F10
Run. Menjalankan aplikasi ke emulator atau devices. - Shift+F9
Debug. Menjalankan aplikasi ke emulator atau devices dalam mode Debug, biasanya untuk keperluan testing.
Code Completion
Untuk meminimalisir salah ketik (typo) dalam pemanggilan class, method hingga variabel sebaiknya kita memanfaatkan Code Completion di Android Studio. Terdapat dua jenis code completion yang sering digunakan di Android Studio:
- Basic Code Completion (Ctrl+Space)
Pemanggilan code completion standar untuk membantu kita melengkapi kode.Ketika kita ingin memanggil sebuah variabel, cukup ketikkan code completion di atas. Kemudian saran pun akan diberikan.
- Statement Completion (Ctrl+Shift+Enter)
Perintah ini sangat membantu karena kita bisa menyelesaikan kode tanpa harus mengetik lengkap dan tanpa tanda kurung, kurung siku, kurung kurawal, serta banyak macam pemformatan lainnya.
Kode di bawah ini ditulis sebelum menggunakan shortcut:Kemudian kita menggunakan Statement Completion. Lihat apa yang terjadi!
Statement kita yang belum tuntas akan diselesaikan oleh Android Studio. Tentu hal ini akan mempercepat waktu kita dalam menggarap aplikasi.
Selengkapnya Anda dapat mempelajarinya di sini.
Style dan Formatting
Gaya penulisan kode adalah seni dalam pemrograman. Kita memiliki signature style masing-masing, Semua tergantung pilihan kita sendiri. Tetapi kita tetap perlu memperhatikan bagaimana tata letak kode, apalagi bila suatu saat nanti kita membuat aplikasi bersama orang lain. Kode yang rapi itu enak dilihat dan memudahkan, baik kita maupun orang lain untuk membacanya. Secara default Android Studio memberikan code style formatting untuk tata letak kode yang kita miliki. Untuk menyesuaikan setelan code style, klik File > Settings > Editor > Code Style (Android Studio > Preferences > Editor > Code Style pada Mac.)
Bagaimana menurut Anda tentang kode di atas? Ya tidak ada yang salah. Namun, code style berantakan dan tidak indah untuk dilihat.
Nah, kini kita akan melakukan kode formatting dengan menggunakan shortcut Ctrl+Alt+L.
Hasilnya lebih baik, bukan?
Mungkin bila kode yang kita miliki sedikit, tidak terlalu berpengaruh. Namun, bila baris kode sudah mulai kompleks, formatting code seperti ini akan sangat membantu.
Sample Code
Android Studio juga membantu kita menemukan kode yang berkualitas dan best practice-nya. Melalui Google, Android Studio memiliki sample code yang bebas kita gunakan dan manfaatkan untuk kebutuhan kita belajar atau membuat aplikasi Android. Dengan mengakses File > New > Import Sample, kita punya banyak pilihan contoh kode yang bisa dipakai. Selengkapnya dapat kita jumpai di sini.
Keren, kan? Jadi biasakan diri Anda menggunakan alat bantu dari Android Studio untuk membantu dan mempercepat pembuatan aplikasi.
Menjalankan Aplikasi di Device & Emulator
Uji coba aplikasi wajib dilakukan seorang developer. Proses running atau debugging bisa dilakukan dengan dua cara, yaitu running dengan peranti (physical device) atau emulator. Emulator adalah tool yang mensimulasikan OS Android di dalam komputer. Baik device langsung maupu emulator memiliki kelebihan dan kekurangan masing-masing. Kita sebagai developer tinggal pilih mana yang sesuai dengan keperluan.
Persiapan Running Menggunakan Emulator
Sebelum menggunakan emulator, pastikan beberapa hal berikut ini:
Virtualization
Untuk menjalankan emulator di dalam Android Studio, pastikan aspek virtualization. Sistem Anda harus memenuhi persyaratannya, yakni ketentuan prosesor dan sistem operasi dari laptop / PC yang Anda gunakan.
Processor
- Prosesor Intel: Jika laptop/pc Anda menggunakan prosesor Intel, maka pastikan ia mendukung Intel VT-x, Intel EM64T (Intel 64), dan Execute Disable (XD) Bit functionality.
- Prosesor AMD: Jika laptop/pc Anda menggunakan AMD, maka pastikan bahwa ia support dengan AMD Virtualization (AMD-V) dan Supplemental Streaming SIMD Extensions 3 (SSSE3).
Sistem Operasi
- Intel: Jika menggunakan processor Intel maka Anda dapat menjalankannya di sistem operasi Windows, Linux, maupun Mac.
- AMD: Untuk prosesor AMD maka hanya bisa menjalankannya di sistem operasi Linux.
Konfigurasi Hardware Accelerated Execution Manager (HAXM)
Dalam beberapa device yang tidak mendukung Emulator, Anda perlu menginstal HAXM. HAXM adalah hardware-assisted virtualization engine yang menggunakan teknologi VT dari Intel untuk mempercepat aplikasi Android yang diemulasi di mesin host. HAXM diperlukan untuk menjalankan emulator di Android Studio.
HAXM diperlukan jika sistem operasi yang Anda gunakan adalah Windows atau Mac. Untuk menginstalnya, ikuti petunjuk berikut ini.
- Buka SDK Manager.
- Pilih SDK Update Sites, kemudian hidupkan Intel HAXM.
- Tekan OK.
- Cari berkas installer-nya di directory folder sdk komputer Anda,
~sdk\extras\intel\Hardware_Accelerated_Execution_Manager\intelhaxm-android.exe. - Jalankan installer dan ikuti petunjuknya sampai selesai.
Catatan:
Jika HAXM sudah otomatis ter-install, maka Anda dapat melewati langkah di atas.
Menginstal Kernel-based Virtual Machine (KVM) untuk Pengguna Linux
Karena HAXM hanya untuk Windows dan Mac, bagaimana dengan sistem operasi Linux? Untuk Linux, Anda harus menginstal KVM. Sistem operasi Linux dapat support accelerated virtual machine dengan menggunakan KVM. Untuk instal KVM, Anda bisa menggunakan perintah berikut ini.
$ sudo apt-get install qemu-kvm libvirt-bin ubuntu-vm-builder bridge-utils ia32-libs-multiarch
Selengkapnya dapat Anda baca pada halaman berikut ini:
- https://developer.android.com/studio/run/emulator.html
- https://developer.android.com/studio/run/emulator-acceleration.html
Run dengan device
Bila Anda hendak melakukan run atau debugging, lebih baik Anda menjalankannya pada peranti smartphone asli. Running dengan menggunakan peranti memiliki beberapa kelebihan jika dibandingkan dengan emulator yaitu:
- Lebih cepat dan ringan,
- Fitur seperti geo-location, push notif bisa digunakan,
- Bisa mengetahui daya serap baterai terhadap aplikasi,
- Lebih mudah.
Dengan menggunakan peranti smartphone asli, kita dapat memastikan bahwa aplikasi kita berjalan dengan wajar ketika sudah sampai di tangan pengguna. Kendala dari pendekatan ini adalah beragamnya model peranti yang ada di pasaran. Namun, pembahasan mengenai hal tersebut tidak tercakup dalam kelas ini.
Mari ikuti langkah-langkah untuk menjalankan proses run atau debugging. Tampilan dari langkah berikut bisa dipastikan akan berbeda dengan peranti yang Anda pakai. Akan tetapi secara garis besar langkahnya akan sama.
- Pastikan peranti yang akan dipakai sesuai dengan target SDK atau paling tidak mendukung versi SDK terendah yang digunakan aplikasi.
- Buka setting dan masuk ke dalam menu About. Pada halaman menu ini, Anda perlu menemukan informasi tentang Build number.
Kemudian tekan Build number sebanyak 7 kali.
Kembali ke menu setting di awal dan akan muncul menu baru di bawah about yaitu Developer Options.
Masuk ke dalam menu Developer Options dan pastikan opsi USB Debugging Mode sudah on.
Catatan : Beberapa vendor smartphone memiliki sistem operasi yang unik. Tampilan setting dan letak opsi bisa jadi tak sama dengan gambar di atas. Beberapa vendor juga mengharuskan Anda untuk mengunduh driver khusus sebelum bisa menghubungkannya ke Android Studio. Kami sarankan untuk mengunjungi website atau membaca petunjuk yang sesuai dengan vendor dari peranti Anda.
Anda bisa unduh ADB Driver di tautan berikut:
Setelah menyelesaikan pengaturan pada peranti, peranti pun dapat dihubungkan dengan laptop atau komputer dengan menggunakan kabel data. Klik Izinkan dan centang untuk selalu izinkan apabila muncul pop up Izinkan debugging USB.
Selain menggunakan kabel data, saat ini juga tersedia fitur wireless debugging di Android Studio. Anda hanya cukup menghubungkan device ke jaringan Wi-Fi yang sama dengan PC. Kemudian pada tool window Device Manager, pilih tab Physical, klik Pair Using Wi-Fi, dan scan QR code yang muncul.
Jika device sudah terdeteksi pada Android Studio, ia akan otomatis muncul pada daftar device dan Anda bisa menjalankan aplikasi dengan klik ikon segitiga hijau berikut:
Menggunakan Emulator
Jika Anda memiliki spesifikasi laptop yang lumayan tinggi, Anda dapat juga menggunakan emulator untuk menjalankan aplikasi langsung di PC Anda tanpa perlu menggunakan device. Penasaran caranya, silakan ikuti langkah-langkah berikut.
- Buka AVD Manager dengan klik icon berikut:
- Akan muncul Kemudian pilih Create device.
Akan muncul dialog dengan pilihan beberapa emulator yang bisa Anda pilih. Pilih salah satu dan klik Next.
Kemudian pilih satu system image, usahakan pilih versi Android yang terbaru dan klik Next.
Jika anda ingin membuat spesifikasi hardware (perangkat keras) sendiri, Anda bisa memilihnya pada pilihan New Hardware Profile. Akan muncul dialog seperti di bawah ini.
Anda dapat menentukan konfigurasi hardware sesuai dengan kebutuhan Anda. Yang perlu diingat adalah untuk menggunakan konfigurasi emulator yang sesuai dengan kemampuan laptop atau komputer yang Anda gunakan.
Anda dapat membuat hardware emulator baru atau memilih hardware emulator yang sudah ada. Setelah memilih hardware emulator, akan muncul dialog seperti ini.
Pada dialog ini Anda akan memilih versi android dari emulator yang akan anda buat. Pada dialog tersebut, Anda perlu memilih versi yang sudah diunduh yaitu Nougat. Tombol download di sebelah kanan versi menunjukkan bahwa Anda perlu mengunduhnya terlebih dahulu jika ingin menggunakannya.
Selanjutnya klik Next. Akan muncul dialog verify configuration. Pada dialog ini, Anda bisa memeriksa konfigurasi dari emulator yang Anda pilih.
Pada bagian kiri bawah, terdapat tombol Show Advanced Settings. Bila Anda menekan tombol ini, akan muncul tampilan dialog baru seperti gambar di bawah ini.
Pada bagian advanced setting, Anda bisa mengubah konfigurasi hardware yang telah ditentukan sebelumnya.
Jika sudah selesai, Anda dapat menekan tombol Finish. Anda dapat membuka emulatornya dengan menekan tombol hijau yang ada di sebelah kanan.
Pengaturan emulator sudah selesai dan bisa langsung dijalankan.
Secara default, emulator akan muncul di dalam tool window. Jika Anda ingin mengubahnya, buka File → Settings → Cari Tools Emulator atau menggunakan keyword Emulator → Ubah Launch in a tool window dalam keadaan tidak tercentang.
Catatan :
Menggunakan emulator dari Android Studio kadang terasa berat untuk beberapa device dengan spesifikasi rendah. Untuk mengatasinya Anda bisa menjalankan langsung pada device Android dengan mengikuti langkah selanjutnya atau menggunakan emulator pihak ketiga yang lebih ringan seperti :
Pilih salah satu emulator di atas, kemudian install dan jalankan aplikasinya. Maka emulator tersebut akan otomatis muncul di List Virtual Devices pada Android Studio.
Membuat APK dan AAB
Salah satu langkah terakhir yang perlu dilakukan setelah mengembangkan aplikasi Android adalah mempublikasikan Aplikasi Anda supaya bisa dijalankan oleh orang lain. Ada jenis format yang perlu Anda ketahui, yaitu APK dan AAB.
- APK (Android Package): merupakan berkas executable yang bisa langsung dijalankan di dalam OS Android. Jika Anda belum memahami berkas APK, Anda dapat menyamakannya dengan berkas exe di windows atau ipa di iOS.
- AAB (Android App Bundle): merupakan berkas yang didistribusikan oleh Google Play ke pengguna. Jadi, ketika Anda hendak memublikasikan Aplikasi Anda ke Google Play, berkas inilah yang harus Anda unggah. Dengan format ini, ukuran aplikasi yang diunduh bisa menjadi jauh lebih kecil. Hal ini karena sifatnya yang dinamis, di mana ia dapat mengunduh hanya bagian (seperti bahasa, arsitektur, dan density) yang diperlukan saja.
Cara membuat kedua file ini di Android terbilang cukup mudah. Anda dapat menggunakan sebuah wizard atau melalui command line. Pada modul ini, kita akan fokus menggunakan wizard.
Dari sisi kredibilitas, ada 2 macam berkas APK/AAB yang dapat Anda buat.
- Unsigned APK/AAB: merupakan berkas yang digunakan untuk pengujian saja.
- Signed APK/AAB: merupakan berkas yang digunakan untuk diupload ke PlayStore. Bedanya yaitu memerlukan keystore.
Keystore adalah sebuah berkas biner yang berisi informasi tentang satu atau lebih private key. Private key ini digunakan untuk mencegah pemalsuan aplikasi. Konsep umumnya adalah:
- Sistem Operasi Android mewajibkan semua APK di-sign sebelum terpasang ke dalam device.
- Proses signing ini membutuhkan Public dan Private Key.
- Proses signing ini berlangsung selama pembuatan APK dalam mode debug maupun released.
- Sebuah sertifikat digital public key, atau identity certificate, berisi informasi mengenai sertifikat itu sendiri dan metadata dari pemilik sertifikat tersebut. Pemilik sertifikat ini biasanya adalah developer yang mengembangkan aplikasi.
- Public key yang digunakan dalam proses signing di atas akan dilampirkan di dalam berkas APK. Proses ini dilakukan secara otomatis oleh Android Studio.
- Ketika Anda hendak memperbarui Aplikasi Anda pada Google Play, maka Google Play hanya akan menerimanya bila keystore yang digunakan sama dengan keystore yang pertama kali Anda gunakan ketika mengunggah Aplikasi tersebut ke Google Play.
Kegunaan lain dari keystore adalah:
- Untuk integrasi ke layanan Google seperti Google Maps dengan menggunakan nilai hash (digest SHA1) di dalamnya.
- Untuk integrasi ke layanan API Facebook dengan menggunakan key hash base64 yang terkandung di dalam keystore.
Keystore merupakan sebuah berkas penting yang harus Anda jaga, terlebih ketika aplikasi Anda memiliki jumlah unduhan pengguna yang banyak. Sebabnya, kelalaian menjaga keystore ini dapat menghalangi Anda untuk memperbarui aplikasi. Akibat terburuk adalah Anda harus melakukannya dari awal lagi.
Berikut adalah tips yang bisa Anda gunakan untuk mengamankan keystore :
- Pilih kata kunci (password) yang sulit ditebak. Kombinasikan angka, alfabet dan simbol dalam membuatnya.
- Jangan memberikan keystore kepada orang yang tidak dipercaya apalagi meletakkannya di dalam berkas proyek aplikasi.
- Letakan di tempat yang Anda ingat dan aman tentunya.
Untuk memahami hal di atas lebih jauh, baca tautan berikut:
Jika Anda ingin menemukan keystore Anda, maka pengguna Mac dapat menemukannya di ~/.android/debug.keystore. Sementara itu pengguna Windows bisa menemukannya di C:\User\YourUser\.android\debug.keystore.
Catatan:
Pada akhir kelas, Anda akan diminta sebuah project aplikasi Android dengan format APK, cukup yang unsigned saja. Untuk itu, perhatikan baik-baik cara pembuatannya.
Codelab Build APK
Untuk mulai melakukan proses build APK, Anda dapat mengikuti langkah berikut:
- Buka kembali proyek kosong yang telah kita buat sebelumnya.
- Sekarang klik menu Build → Build Bundles(s) / APK(s) → Build APK(s).
Gradle akan membuat berkas APK secara otomatis. Lama proses ini bergantung pada seberapa kompleks Aplikasi yang dibuat serta spesifikasi perangkat yang digunakan.
Ketika berhasil, Anda dapat melihat notifikasi pada sudut kanan atas Android Studio:
Sekarang tinggal Anda tekan tautan yang terdapat pada notifikasi tersebut. Secara otomatis Anda akan diarahkan ke lokasi di mana berkas APK disimpan.
Biasanya lokasinya mengikuti struktur project-name/module-name/build/outputs/apk/. Jika proyek bernama HelloWorld, maka lokasinya adalah HelloWorld/app/build/outputs/apk/apk-debug.apk.
Sekarang coba Anda pindahkan berkas APK yang baru dibuat ke dalam sebuah peranti (device). Buka lokasi berkas tersebut menggunakan file explorer pada gawai tersebut. Kemudian lakukan instalasi aplikasi seperti biasa.
Selamat, aplikasi Android baru Anda sudah terpasang di peranti. Berkas APK ini bisa Anda berikan ke pengguna lain untuk dicoba. Mudah bukan?
Codelab Build Signed AAB
Sekarang kita lanjut membuat AAB dengan keystore. Ingat, APK yang baru saja Anda buat akan ditolak oleh Google Play Store jika Anda mencoba mengunggahnya. Agar dapat diterima, Anda harus memublikasikan dalam format AAB yang sudah ditandatangani dengan menggunakan keystore.
Kembali ke project Android Studio, klik Build → Generate Signed Bundle / APK....
- Selanjutnya, pilih Android App Bundle dan klik Next.
Selanjutnya, pilih Create new... untuk membuat Key store.
Pilihah lokasi penyimpanan pada bagian key store path. Lalu, lengkapi isian di dalamnya. Contoh pengisiannya adalah seperti gambar di bawah ini:
Berikut penjelasan tiap isiannya:
Keystore path Anda perlu menentukan di mana lokasi keystore Anda Password Isikan keystore password minimal 6 digit dan bedakan dengan keypassword di bawahnya Alias Alias dari keystore Password keypassword Validity Berapa lama keystore Anda akan valid (dalam hitungan tahun) Firstname hingga Country Code Isikan metadata. Penting untuk mengisi data ini dengan benar. Setelah selesai klik OK.
Dialog yang di awal akan secara otomatis terisi ketika Anda sudah berhasil mengisi form sebelumnya. Klik Next untuk melanjutkan.
Catatan:
Jika muncul pertanyaan kata kunci, masukkan kata kunci yang Anda gunakan untuk laptop atau komputer.Selanjutnya pilih release dan klik Finish. Selain release yang berguna untuk kepentingan publish ke PlayStore, ada juga debug yang berguna untuk pengujian saja.
Perhatikan gradle process di status bar bagian bawah untuk melihat progress signed/generate AAB.
Ketika berhasil, notifikasi seperti berikut akan tampil.
Selamat AAB versi released Anda telah berhasil dibuat. Untuk membuka folder secara langsung, Anda dapat membuka link locate, selain itu juga ada juga bisa menganalisa hasil file yang dibuat dengan menggunakan analyze.
Proses ini perlu ketika Anda hendak mempublikasikan aplikasi Anda di Google Play Store dan memperbaruinya di kemudian waktu.
Ketika Anda memperbarui aplikasi, jangan lupa untuk mengubah nilai yang ada di dalam build.gradle(Module:app):
versionCode 2 //Incremental versionName "2.0"
Rangkuman Pengenalan Android Studio
- Android Studio adalah IDE (Integrated Development Environment) berbasis Intellij IDEA yang digunakan khusus untuk membangun aplikasi Android.
- Bahasa pemrograman yang bisa digunakan untuk mengembangkan aplikasi Android adalah Kotlin dan Java. Namun, yang direkomendasikan dari Google adalah Kotlin.
- Android Studio memiliki fitur yang lengkap untuk mengembangkan aplikasi seperti berikut.
- Template: template memulai project maupun Activity tanpa harus membuatnya dari nol.
- Intelligent code editor: code completion yang memudahkan untuk menulis kode dengan cepat tanpa harus menuliskan secara lengkap. Selain itu, juga ada warning apabila terdapat kesalahan penulisan kode.
- Design tool: digunakan untuk mendesain aplikasi beserta melihat preview secara langsung sebelum dijalankan.
- Flexible build system: Android Studio menggunakan Gradle yang fleksibel untuk menciptakan build variant yang berbeda untuk berbagai device. Anda juga dapat menganalisa prosesnya secara mendetail.
- Emulator: menjalankan aplikasi tanpa harus menggunakan device Android. Dilengkapi dengan Instant Run untuk melihat perubahan tanpa harus build project dari awal.
- Debugging: memudahkan untuk mencari tahu masalah.
- Testing: menjalankan pengujian untuk memastikan semua kode aman sebelum rilis.
- Publish: membuat berkas AAB/APK dan menganalisanya guna dibagikan dan di-publish ke PlayStore.
- Integrasi: Terhubung dengan berbagai layanan yang memudahkan untuk mengembangkan aplikasi, seperti Github, Firebase, dan Google Cloud.
- JRE (Java Runtime Environment) adalah Virtual Machine untuk menjalankan program Java, sedangkan JDK (Java SE Development Kit) merupakan compiler dan tools untuk membuat program.
- Untuk melihat proses instalasi Android Studio secara lebih detail di masing-masing OS, Anda dapat melihatnya pada tautan berikut.
- Android SDK adalah sekumpulan tool yang digunakan untuk mengembangkan aplikasi Android.
- Berikut adalah beberapa cara untuk membuat project baru pada Android Studio.
- Ketika pertama kali membuka Android Studio dan muncul window “Welcome to Android Studio”, klik “Start a new Android Studio project.”
- Jika sudah membuka project lain, klik File → New → New Project.
- Package name: digunakan sebagai identifikasi unik dari aplikasi ketika di-publish di PlayStore. Antara satu aplikasi dengan aplikasi lainnya harus berbeda. Biasanya penamaan package menggunakan format domain, tetapi urutannya dibalik.
- Minimum SDK: digunakan untuk menentukan versi minimum Android yang dapat menjalankan project ini. Anda dapat membuka Help me choose pada saat membuat project untuk melihat distribusi pemakai Android pada setiap versi sehingga bisa menentukan minimum SDK yang cocok.
- Saat versi baru Android dirilis, developer hendaknya terus mengikuti best-practice terbaru untuk memastikan aplikasi yang dibuat tetap memberikan pengalaman yang terbaik di sebanyak mungkin device. Untuk mencari tahu tentang versi terbaru, Anda dapat melihatnya pada tautan berikut.
- Berikut adalah bagian-bagian dari antarmuka Android Studio.
- Toolbar: merupakan tools yang sering digunakan dalam development, mulai dari copy/paste, build, menjalankan aplikasi, hingga menjalankan emulator.
- Navigation bar: membantu untuk melihat struktur dari kedalaman (depth) dan posisi proyek yang saat ini sedang dibuka.
- Project Explorer dan Editor: bagian utama dari IDE untuk melihat struktur project dan menulis kode
- Tool Window Bar: menu yang mengelilingi editor ini merupakan button yang dapat di-expand atau menampilkan tools secara detail dan individual.
- Status Bar: terletak di bagian paling bawah dalam Android Studio, ia berfungsi untuk menampilkan status proyek dan pesan peringatan (warning message) bila ada.
- AndroidManifest merupakan file XML yang memberikan beragam informasi penting kepada sistem Android sebelum aplikasi dijalankan.
- Tag application berfungsi untuk mendeskripsikan komponen dasar aplikasi Android, mulai dari activity, services, broadcast receiver, dan content provider.
- Tag uses-permission berfungsi untuk menentukan izin yang harus dimiliki oleh aplikasi untuk mengakses sistem, seperti internet, external storage, contact, lokasi, dan lain sebagainya.
- Folder java dengan folder sesuai nama package digunakan untuk meletakkan berkas source code yang ditulis dalam bahasa Kotlin/Java, termasuk juga source set test untuk Unit Test dan androidTest untuk Instrumentation Test.
- Folder res digunakan untuk mengatur resource di dalam aplikasi seperti berikut.
- drawable: untuk menyimpan berkas gambar maupun ikon.
- layout: untuk menyimpan berkas desain aplikasi yang berupa XML.
- mipmap: untuk menyimpan logo dalam berbagai dimensi.
- values: berisi berbagai macam sumber data, seperti colors.xml untuk warna, strings.xml untuk teks, dimens.xml untuk ukuran, dan themes.xml untuk membuat theme dan style.
- Selain itu, juga ada jenis folder resource yang bisa Anda tambahkan seperti yang ada pada tautan berikut.
- Gradle merupakan open source build automation system. Automation system berguna untuk mengotomatisasi proses pembuatan dari software build dan proses-proses terkait lainnya termasuk compile source code menjadi binary code, packaging binary code, dan menjalankan automated test.
- Ada dua jenis gradle script yang biasa Anda ubah ketika membangun aplikasi.
- build.gradle Level Project: merupakan software build tingkat teratas yang meliputi keseluruhan dari proyek dari sebuah aplikasi. Di dalamnya berisi konfigurasi library Android dan Kotlin untuk semua module.
- build.gradle Level Module: merupakan software build yang ada pada setiap module. Beberapa konfigurasi yang diedit di antaranya adalah android settings, defaultConfig dan productFlavors, buildTypes, dan dependencies.
- Berikut adalah beberapa detail konfigurasi yang dapat diubah pada gradle script level modul.
- namespace: package name unik yang digunakan untuk Play Store, sama seperti yang kita atur pada saat membuat project.
- compileSdk: merupakan versi SDK yang digunakan untuk meng-compile project.
- applicationId: biasanya sama dengan namespace, nilainya bisa berubah untuk kebutuhan build variant.
- minSdk: merupakan versi SDK minimal yang didukung oleh project ini. Android dengan versi di bawahnya tidak dapat menjalankan aplikasi ini.
- targetSdk: target versi SDK yang menandakan aplikasi ini sudah dites pada versi SDK tertentu. Best practice-nya adalah memilih SDK yang terbaru. Jika tidak didefinisikan, nilainya sama dengan minSdk.
- versionCode: nilai integer yang menandakan versi dari aplikasi. Apabila aplikasi sudah di-publish di PlayStore dengan versionCode 1, kita perlu mengubah versionCode menjadi 2 (incremental satu tingkat) ketika ingin meng-update aplikasinya lagi. Jika tidak diubah, PlayStore akan menolak APK yang di-upload.
- versionName: versi aplikasi berupa String yang biasa ditunjukkan ke user, misalnya 1.0.1.
- buildTypes: di dalamnya terdapat properties dari debuggable, ProGuard enabling, debug signing, version name suffix dan test information.
- dependencies: di dalamnya terdapat informasi tentang library yang digunakan oleh aplikasi.
- Berikut adalah beberapa shortcut yang sering digunakan pada Android Studio.
- Shift+Shift: pencarian semua jenis berkas yang masih dalam 1 proyek.
- Ctrl+Shift+F: pencarian teks di seluruh berkas proyek.
- Ctrl+D : menggandakan bagian yang dipilih.
- Ctrl+Q : melihat dokumentasi dengan tampilan minimal.
- Alt+Enter: melihat solusi pada kode yang error.
- Ctrl+Alt+L: memformat ulang atau merapikan kode.
- Shift+F10: menjalankan aplikasi ke emulator atau devices.
- Untuk meminimalisir salah ketik (typo) dalam pemanggilan class, method hingga variabel sebaiknya memanfaatkan Code Completion di Android Studio. Terdapat dua jenis code completion yang sering digunakan di Android Studio.
- Basic Code Completion (Ctrl+Space): pemanggilan code completion standar untuk membantu kita melengkapi kode.
- Statement Completion (Ctrl+Shift+Enter): perintah ini sangat membantu karena kita bisa menyelesaikan kode tanpa harus mengetik lengkap dan tanpa tanda kurung, kurung siku, kurung kurawal, serta banyak macam pemformatan lainnya.
- Emulator adalah tool yang menyimulasikan OS Android di dalam komputer.
- Berikut adalah beberapa alternatif untuk menjalankan project Android.
- Android Virtual Device (AVD), emulator bawaan dari Android Studio.
- Emulator ketiga (Memu, Nox, Genymotion, Bluestack, dll).
- Physical device (perlu mengaktifkan Developer Mode).
- Berikut adalah langkah-langkah untuk mengaktifkan Developer Mode pada device.
- Settings → About Phone → Tekan Build Number 7 kali.
- Settings → Developer Options → Aktifkan USB debugging.
- Hubungkan device dengan komputer via USB.
- Ada dua jenis format yang perlu Anda ketahui untuk memublikasikan aplikasi.
- APK (Android Package): merupakan berkas executable yang bisa langsung dijalankan di dalam OS Android.
- AAB (Android App Bundle): merupakan berkas yang didistribusikan oleh Google Play ke pengguna. Dengan format ini, ukuran aplikasi bisa menjadi jauh lebih kecil karena ia hanya mengunduh bagian (seperti bahasa, arsitektur, dan density) yang diperlukan saja.
- Dari sisi kredibilitas, ada 2 macam berkas APK/AAB yang dapat Anda buat.
- Unsigned APK/AAB: merupakan berkas yang digunakan untuk pengujian saja.
- Signed APK/AAB: merupakan berkas yang digunakan untuk diupload ke PlayStore. Bedanya yaitu memerlukan keystore.
- Keystore adalah sebuah berkas biner yang berisi informasi tentang satu atau lebih private key untuk mencegah pemalsuan aplikasi. Berkas penting ini harus dijaga dan disimpan karena dibutuhkan setiap kali membuat Signed AAB untuk meng-update aplikasi.
Ini adalah modul untuk menguji pengetahuan Anda tentang materi yang telah dipelajari. Terdapat 4 pertanyaan yang harus dikerjakan dalam ujian ini. Beberapa ketentuan dari ujian ini adalah:
- Syarat nilai kelulusan : 75%
- Durasi ujian : 5 menit
Apabila tidak memenuhi syarat kelulusan, maka Anda harus menunggu selama 1 menit untuk mengulang pengerjaan ujian kembali.
Selamat Mengerjakan!
Teori Activity
Activity merupakan salah satu komponen penting Android yang berfungsi untuk menampilkan user interface ke layar pengguna. Ini seperti pada saat Anda melihat daftar percakapan pada aplikasi chat atau daftar email pada aplikasi Gmail di ponsel Android Anda. Di dalamnya Anda dapat berinteraksi dengan aplikasi Anda, baik dengan menekan tombol atau menampilkan list.
Seperti ketika Anda membuat project baru di Android Studio, biasanya akan ada dua berkas yang sudah tercipta, yaitu MainActivity dan activity_main.xml. MainActivity ini disebut sebagai class Activity karena mewarisi (extends) superclass Activity. Tugasnya yaitu menampilkan layout activity_main.xml dan mengelola interaksi yang ada di dalamnya.
Umumnya dalam sebuah aplikasi terdapat lebih dari satu Activity yang saling terhubung dengan tugas yang berbeda-beda. Yang perlu diperhatikan yaitu setiap Activity harus terdaftar di AndroidManifest.xml. Secara default, ia akan didaftarkan jika Anda membuat Activity baru dengan cara otomatis. Caranya yaitu klik kanan pada nama package → New → Activity → pilih template Activity yang tersedia.
Activity Lifecycle
Developer yang baik harus mengetahui secara detail tentang life cycle sebuah Activity. Terutama untuk melakukan aksi yang tepat, saat terjadi perubahan state Activity. Callback methods yang ada dapat digunakan untuk melakukan beragam proses terkait state dari Activity. Misalnya melakukan semua inisialisasi komponen di onCreate(), melakukan disconnect terhadap koneksi ke server pada onStop() atau onDestroy() dan lain sebagainya.
Pemahaman yang baik tentang daur hidup Activity akan membuat implementasi rancangan aplikasi Anda menjadi lebih baik. Hal ini juga akan meminimalisir terjadinya error/bug/force close yang tidak diinginkan.
Last In, First Out (LIFO)
Gambar 1 | Gambar 2 | Gambar 3 |
---|---|---|
Aktif: Activity 1 onCreate() → onStart() → onResume() | Aktif: Activity 2 Stack append: Activity 2 [ onResume() ] | Activity 1 onStop() → onRestart() → onStart() → onResume() |
Aksi: Klik Button1 (Pindah) | Aksi: Klik Hardware Back Button | Aktif: Activity 1 |
Stack append: Activity 1 [ onStop() ] | Activity 2 [ finish() ] Stack pop: Activity 2 [ onDestroy() ] |
Gambar 1
Jika Anda memiliki sebuah aplikasi yang terdiri dari 2 Activity, maka Activity pertama akan dijalankan setelah pengguna meluncurkan aplikasi melalui ikon aplikasi di layar device. Activity yang ada saat ini berada pada posisi Activity running setelah melalui beberapa state onCreate (created) → onStart (started) → onResume (resumed) dan masuk ke dalam sebuah stack Activity.
Bila pada Activity pertama Anda menekan sebuah tombol untuk menjalankan activity kedua, maka posisi state dari Activity pertama berada pada posisi stop. Saat itu, callback onStop() pada Activity pertama akan dipanggil.
Ini terjadi karena Activity pertama sudah tidak berada pada layar foreground / tidak lagi ditampilkan. Semua informasi terakhir pada Activity pertama akan disimpan secara otomatis. Sementara itu, Activity kedua masuk ke dalam stack dan menjadi Activity terakhir yang masuk.
Gambar 2
Activity kedua sudah muncul di layar sekarang. Ketika Anda menekan tombol back pada physical button menu utama atau menjalankan metode finish(), maka Activity kedua Anda akan dikeluarkan dari stack.
Pada kondisi di atas, state Activity kedua akan berada pada destroy. Oleh karenanya, metode onDestroy() akan dipanggil. Kejadian keluar dan masuk stack pada proses di atas menandakan sebuah model Last In, First Out. Activity kedua menjadi yang terakhir masuk stack (Last In) dan yang paling pertama keluar dari stack (First Out).
Gambar 3
Activity pertama akan dimunculkan kembali di layar setelah melalui beberapa state dengan rangkaian callback method yang terpanggil, onStop → onRestart → onStart → onResume.
Saving Activity State
Ketika sebuah Activity mengalami pause kemudian resume, maka state dari sebuah Activity tersebut dapat terjaga. Sebabnya, obyek activity masih tersimpan di memory sehingga dapat dikembalikan state-nya.
Dengan menjaga state dari Activity, maka ketika Activity tersebut ditampilkan, kondisinya akan tetap sama dengan kondisi sebelumnya.
Akan tetapi ketika sistem menghancurkan Activity untuk keperluan memori misalnya karena memori habis, maka obyek Activity dihancurkan. Alhasil, ketika Activity ingin ditampilkan kembali diperlukan proses recreate Activity yang dihancurkan tadi.
Kejadian di atas adalah hal yang lumrah terjadi. Oleh karena itu, perubahan yang terjadi pada Activity perlu disimpan terlebih dahulu sebelum ia dihancurkan. Di sinilah metode onSaveInstanceState() digunakan.
Dalam onSaveInstanceState terdapat bundle yang dapat digunakan untuk menyimpan informasi. Informasi dapat disimpan dengan memanfaatkan fungsi seperti putString() dan putInt().
Ketika Activity di-restart, bundle akan diberikan kepada metode onCreate dan onRestoreInstanceState. Bundle tersebut akan dimanfaatkan untuk mengembalikan kembali perubahan yang telah terjadi sebelumnya.
Proses penghancuran Activity dapat juga terjadi ketika terdapat perubahan konfigurasi seperti perubahan orientasi layar (portrait-landscape), keyboard availability, dan perubahan bahasa. Penghancuran ini akan menjalankan callback method onDestroy dan kemudian menjalankan onCreate. Penghancuran ini dimaksudkan agar Activity dapat menyesuaikan diri dengan konfigurasi baru yang muncul pada kejadian-kejadian sebelumnya.
Hal yang perlu diingat ketika menggunakan onSaveInstanceState adalah untuk tidak menyimpan data yang besar pada bundle. Contohnya, hindari penyimpanan data bitmap pada bundle. Bila data pada bundle berukuran besar, proses serialisasi dan deserialisasi akan memakan banyak memori.
Untuk lebih mendalami Activity, kami menyarankan Anda untuk membaca referensi berikut :
Tujuan
Codelab ini bertujuan untuk mengimplementasikan komponen Activity pada aplikasi pertama yang Anda bangun. Harapannya aktifitas ini dapat memberi gambaran yang jelas tentang cara kerja Activity.
Codelab pertama adalah dengan membuat aplikasi yang dapat menghitung volume balok. Seperti ini tampilannya.
Logika Dasar
Melakukan input ke dalam obyek EditText → melakukan validasi input → melakukan perhitungan volume balok ketika tombol hitung diklik.
Codelab Membuat Proyek Baru
Hai! Pasti sudah tidak sabar ya untuk memulai membuat aplikasi pertama kalian. Sebelum mulai lebih lanjut, ada video menarik nih buat teman-teman supaya bisa mendapatkan gambaran terlebih dahulu bagaimana proses pembuatan aplikasi pertama. Silakan dicek ya!
Okay, jika sudah dapat gambarannya, yuk kita lanjut untuk bikin aplikasinya. Cuss!
Buat proyek baru dengan klik File → New → New Project pada Android Studio Anda atau Anda bisa memilih Start a new Android Studio project di bagian dashboard.
Windows iOS - Pada bagian ini kita akan memilih tipe activity awal dari template yang telah disediakan.
Untuk saat ini, pilih tipe Empty Activity untuk belajar dari yang paling dasar, lalu klik Next untuk melanjutkan.
- Selanjutnya masukkan nama aplikasi dan nama package aplikasi Anda. Sebaiknya jangan sama dengan apa yang ada di contoh, karena ini berfungsi sebagai id dari aplikasi yang Anda buat. Kemudian Anda bisa menentukan lokasi proyek yang akan Anda buat. Setelah itu pilih tipe gawai/peranti (device) untuk aplikasi beserta target minimum SDK yang akan digunakan. Pilihan target Android SDK akan mempengaruhi banyaknya peranti yang dapat menggunakan aplikasi. Di sini kita memilih nilai minimum SDK kita pasang ke Level 21 (Lollipop). Klik Finish untuk melanjutkan.
Catatan:
Kotlin merupakan rekomendasi Google dalam pembuatan aplikasi ini. Namun, kelas ini juga mendukung bahasa Java. Untuk menggunakan bahasa Java, ubahlah language dari Kotlin menjadi Java, maka secara otomatis Android Studio akan menyesuaikan dengan bahasa Java. - Tampilan layar Anda akan seperti contoh di bawah ini:
- Di sebelah kanan Anda adalah workspace di mana Activity Anda berada dan bernama MainActivity dengan layout-nya activity_main.xml. Di sebelah kiri Anda terdapat struktur proyek, di mana nanti kita akan banyak menambahkan berbagai komponen baru, asset dan library.
Selanjutnya kita akan mulai melakukan pengkodean aplikasi atau lebih enaknya disebut ngoding. Berikut flow umumnya:
- Ngoding Layout untuk user interface aplikasi.
- Ngoding Activity untuk menambahkan logika aplikasi.
Untuk mengoptimalkan proses pengetikan, Anda dapat memanfaatkan code completion dengan menekan ctrl + space. Android Studio juga akan otomatis mengimpor package dari komponen yang digunakan.
Dilarang Keras untuk copy - paste! Ngoding pelan-pelan akan membuat Anda lebih jago di masa depan.
Selamat ngoding!
Codelab Layouting
Menambahkan Code Sederhana pada Layout Activity
- Silakan pilih berkas activity_main.xml pada workspace Anda yang terletak di folder res/layout/activity_main.xml.
Pastikan project window pada pilihan Android seperti di bawah ini.
Maka akan ada tampilan seperti ini di sebelah pojok kanan atas, kemudian pilih tab Code atau Split.
- Ubah layout dasar dari ConstraintLayout menjadi LinearLayout seperti berikut:
Catatan:
Pada latihan awal ini kita akan menggunakan LinearLayout karena merupakan layout yang paling mudah. Pembahasan lebih lanjut tentang macam-macam layout akan dibahas pada materi selanjutnya. Jadi ikuti saja dulu ya! - Perhatikan bahwa dalam penulisan kode XML, ada dua cara dalam penulisan tag seperti gambar di bawah ini.
- Self-closing tag: tag diawali dengan < dan diakhiri dengan />. Biasanya digunakan untuk View tanpa isi.
- Opening dan closing tag: opening tag diawali dengan < dan diakhiri dengan > saja. Sebagai gantinya, ada closing tag dengan format </NamaView>. Biasanya digunakan untuk layout yang menampung View lain di dalamnya.
- Selanjutnya tambahkan baris-baris yang dicetak tebal di bawah ini. Berikut adalah contoh cara menuliskannya. Perhatikan bahwa dalam penulisan kode, kita tidak perlu menuliskan kode secara lengkap. Manfaatkanlah snippet untuk code completion yang muncul dan tekan Enter.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Panjang" /> <EditText android:id="@+id/edt_length" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Lebar" /> <EditText android:id="@+id/edt_width" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Tinggi" /> <EditText android:id="@+id/edt_height" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <Button android:id="@+id/btn_calculate" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Hitung" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Hasil" android:textSize="24sp" android:textStyle="bold" /> </LinearLayout>
- Perhatikan bahwa ada warning berwarna kuning pada atribut android:text di layout tersebut.
Ini karena kita melakukan hardcoded (menuliskan teks secara langsung) pada nilai string-nya. Ini merupakan praktik yang kurang baik karena seharusnya kita menuliskan semua teks pada berkas res/values/strings.xml dan setelah itu baru memanggilnya.
Okey, mari kita hilangkan warning tersebut dengan menekan Alt+Enter (option + return pada Mac) atau menekan lampu kuning yang muncul pada attribut android:text. Akan muncul dialog seperti ini, pilih extract string resource. Kemudian akan muncul dialog seperti di bawah ini. Sesuaikan dengan nama yang ada.
Atau bisa juga melihat animasi berikut:
Fungsi extract string resource akan secara otomatis menambahkan nilai dari android:text ke dalam berkas res/values/strings.xml.
Lakukan hal yang sama pada setiap text lainnya. Jika kita buka berkas strings.xml yang ada di folder res/value, maka isinya akan menjadi seperti ini:
<resources> <string name="app_name">BarVolume</string> <string name="width">Lebar</string> <string name="height">Tinggi</string> <string name="calculate">Hitung</string> <string name="result">Hasil</string> <string name="length">Panjang</string> </resources>
Maka kode di dalam activity_main.xml akan menjadi seperti berikut:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/length" /> <EditText android:id="@+id/edt_length" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/width" /> <EditText android:id="@+id/edt_width" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/height" /> <EditText android:id="@+id/edt_height" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="numberDecimal" android:lines="1" /> <Button android:id="@+id/btn_calculate" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/calculate" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/result" android:textSize="24sp" android:textStyle="bold" /> </LinearLayout>
Jika Anda perhatikan, hasil layout sementara akan menjadi seperti ini:
Selain menggunakan code seperti di atas, Anda juga dapat membuat layout dengan menggunakan design. Untuk tutorialnya dapat Anda lihat di video berikut:
Setelah selesai mendesain aplikasi, silakan coba jalankan aplikasi dengan memilih menu Run → Run ‘app’ dari menu bar.
Selain cara di atas, Anda juga dapat menekan icon berikut di toolbar:
Itu tandanya ADB (Android Debugger) pada peranti yang Anda punya telah terhubung dengan Android Studio. Jika Anda tidak memiliki peranti, maka Anda dapat menggunakan emulator. Ikuti materinya di modul sebelumnya atau lihat materi di sini.
Catatan:
Kami merekomendasikan Anda menggunakan peranti Android sewaktu mengembangkan aplikasi. Selain karena beban memori pada peranti Anda akan jadi lebih rendah, pendekatan ini juga akan memungkinkan Anda untuk merasakan bagaimana aplikasi berjalan di device sebenarnya.
Pilih OK untuk menjalankan dan tunggu hingga proses building dan instalasi APK selesai. Jika sudah, seharusnya hasilnya akan seperti ini:Saat ini aplikasi telah tampil, namun ketika Anda coba untuk memasukkan angka dan klik tombol Hitung, aplikasi tidak akan merespons. Hal ini karena kita belum menambahkan logika kode pada MainActivity. Nah, yuk kita lanjut ke codelab selanjutnya supaya aplikasi pertama kita bisa berjalan dengan semestinya. Semangat!
Codelab Kode Logika
Menambahkan Kode Logika Sederhana pada MainActivity.
- Selanjutnya setelah selesai, lanjutkan dengan membuka berkas MainActivity dan lanjutkan ngoding baris-baris di bawah ini.
Tambahkan beberapa variabel yang akan digunakan untuk menampung View.Kotlin private lateinit var edtWidth: EditText private lateinit var edtHeight: EditText private lateinit var edtLength: EditText private lateinit var btnCalculate: Button private lateinit var tvResult: TextView
Catatan:
Perhatikan bagaimana cara menuliskan kodenya. Biasakan menekan Enter ketika mengetik supaya komponen di-import secara otomatis, kecuali nama variabel yang Anda tentukan sendiri seperti edtWidth harus diketik satu per satu.Java private EditText edtWidth; private EditText edtHeight; private EditText edtLength; private Button btnCalculate; private TextView tvResult;
Catatan:
Perhatikan bagaimana cara menuliskan kodenya. Biasakan menekan Enter ketika mengetik supaya komponen di-import secara otomatis, kecuali nama variabel yang Anda tentukan sendiri seperti edtWidth harus diketik satu per satu. - Kemudian inisiasi variabel yang telah kita buat dengan menambahkan kode berikut di dalam metode onCreate.
Kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) edtWidth = findViewById(R.id.edt_width) edtHeight = findViewById(R.id.edt_height) edtLength = findViewById(R.id.edt_length) btnCalculate = findViewById(R.id.btn_calculate) tvResult = findViewById(R.id.tv_result) btnCalculate.setOnClickListener(this) }
Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtWidth = findViewById(R.id.edt_width); edtHeight = findViewById(R.id.edt_height); edtLength = findViewById(R.id.edt_length); btnCalculate = findViewById(R.id.btn_calculate); tvResult = findViewById(R.id.tv_result); btnCalculate.setOnClickListener(this); }
- Akan muncul baris merah pada kata this. Hal ini karena ketika kita menggunakan setOnClickListener(this), maka kita perlu menambahkan interface View.OnClickListener di kelas MainActivity. Silakan klik di atas baris merah tersebut, kemudian tekan tombol Alt + Enter (option + return pada Mac) atau menekan lampu merah yang muncul lalu pilih aksi berikut untuk implement interface.
Maka secara otomatis akan ada penambahan kode pada kelas MainActivity seperti berikut ini:Kotlin Java Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { ... }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { ... }
Jika terdapat baris merah seperti ini:
Jangan khawatir! Silakan klik di atas baris merah tersebut, kemudian tekan tombol Alt + Enter (option + return pada Mac) atau menekan lampu merah yang muncul lalu pilih implement methods (Java) atau implement members (Kotlin).
Kotlin Java Maka secara otomatis akan ada penambahan metode onClick di kelas MainActivity. Setelah itu, tambahkan kode berikut ke dalam metode onClick:
Kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... } override fun onClick(v: View?) { if (v?.id == R.id.btn_calculate) { val inputLength = edtLength.text.toString().trim() val inputWidth = edtWidth.text.toString().trim() val inputHeight = edtHeight.text.toString().trim() val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble() tvResult.text = volume.toString() } }
Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... } @Override public void onClick(View v) { if (v.getId() == R.id.btn_calculate) { String inputLength = edtLength.getText().toString().trim(); String inputWidth = edtWidth.getText().toString().trim(); String inputHeight = edtHeight.getText().toString().trim(); double volume = Double.parseDouble(inputLength) * Double.parseDouble(inputWidth) * Double.parseDouble(inputHeight); tvResult.setText(String.valueOf(volume)); } }
- Akhirnya kelas MainActivity akan memiliki kode seperti berikut ini:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var edtWidth: EditText private lateinit var edtHeight: EditText private lateinit var edtLength: EditText private lateinit var btnCalculate: Button private lateinit var tvResult: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) edtWidth = findViewById(R.id.edt_width) edtHeight = findViewById(R.id.edt_height) edtLength = findViewById(R.id.edt_length) btnCalculate = findViewById(R.id.btn_calculate) tvResult = findViewById(R.id.tv_result) btnCalculate.setOnClickListener(this) } override fun onClick(v: View?) { if (v?.id == R.id.btn_calculate) { val inputLength = edtLength.text.toString().trim() val inputWidth = edtWidth.text.toString().trim() val inputHeight = edtHeight.text.toString().trim() val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble() tvResult.text = volume.toString() } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText edtWidth, edtHeight, edtLength; private Button btnCalculate; private TextView tvResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtWidth = findViewById(R.id.edt_width); edtHeight = findViewById(R.id.edt_height); edtLength = findViewById(R.id.edt_length); btnCalculate = findViewById(R.id.btn_calculate); tvResult = findViewById(R.id.tv_result); btnCalculate.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_calculate) { String inputLength = edtLength.getText().toString().trim(); String inputWidth = edtWidth.getText().toString().trim(); String inputHeight = edtHeight.getText().toString().trim(); double volume = Double.parseDouble(inputLength) * Double.parseDouble(inputWidth) * Double.parseDouble(inputHeight); tvResult.setText(String.valueOf(volume)); } } }
Setelah selesai, silakan jalankan aplikasi kembali. Jika sudah, seharusnya hasilnya akan seperti ini:
Silakan masukkan nilai panjang, lebar, dan tinggi kemudian tekan tombol Hitung dan hasilnya akan ditampilkan di objek textview tvResult. Namun masih ada sedikit masalah di sini, yaitu Anda tetap melakukan proses perhitungan walaupun salah satu nilainya kosong. Hal ini akan menyebabkan aplikasi force close karena perhitungan tidak dapat diproses. Maka untuk mengatasinya Anda akan menggunakan percabangan untuk mengecek apakah masing-masing EditText kosong atau tidak.
- Silakan buka kembali kelas MainActivity. Tambahkan kode berikut ke dalam metode onClicksebelum melakukan perhitungan.
Kotlin override fun onClick(v: View?) { if (v?.id == R.id.btn_calculate) { val inputLength = edtLength.text.toString().trim() val inputWidth = edtWidth.text.toString().trim() val inputHeight = edtHeight.text.toString().trim() var isEmptyFields = false if (inputLength.isEmpty()) { isEmptyFields = true edtLength.error = "Field ini tidak boleh kosong" } if (inputWidth.isEmpty()) { isEmptyFields = true edtWidth.error = "Field ini tidak boleh kosong" } if (inputHeight.isEmpty()) { isEmptyFields = true edtHeight.error = "Field ini tidak boleh kosong" } if (!isEmptyFields) { val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble() tvResult.text = volume.toString() } } }
Java @Override public void onClick(View v) { if (v.getId() == R.id.btn_calculate) { String inputLength = edtLength.getText().toString().trim(); String inputWidth = edtWidth.getText().toString().trim(); String inputHeight = edtHeight.getText().toString().trim(); boolean isEmptyFields = false; if (TextUtils.isEmpty(inputLength)) { isEmptyFields = true; edtLength.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputWidth)) { isEmptyFields = true; edtWidth.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputHeight)) { isEmptyFields = true; edtHeight.setError("Field ini tidak boleh kosong"); } if (!isEmptyFields) { double volume = Double.parseDouble(inputLength) * Double.parseDouble(inputWidth) * Double.parseDouble(inputHeight); tvResult.setText(String.valueOf(volume)); } } }
- Akhirnya kelas MainActivity akan memiliki kode seperti berikut ini:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var edtWidth: EditText private lateinit var edtHeight: EditText private lateinit var edtLength: EditText private lateinit var btnCalculate: Button private lateinit var tvResult: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) edtWidth = findViewById(R.id.edt_width) edtHeight = findViewById(R.id.edt_height) edtLength = findViewById(R.id.edt_length) btnCalculate = findViewById(R.id.btn_calculate) tvResult = findViewById(R.id.tv_result) btnCalculate.setOnClickListener(this) } override fun onClick(v: View?) { if (v?.id == R.id.btn_calculate) { val inputLength = edtLength.text.toString().trim() val inputWidth = edtWidth.text.toString().trim() val inputHeight = edtHeight.text.toString().trim() var isEmptyFields = false if (inputLength.isEmpty()) { isEmptyFields = true edtLength.error = "Field ini tidak boleh kosong" } if (inputWidth.isEmpty()) { isEmptyFields = true edtWidth.error = "Field ini tidak boleh kosong" } if (inputHeight.isEmpty()) { isEmptyFields = true edtHeight.error = "Field ini tidak boleh kosong" } if (!isEmptyFields) { val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble() tvResult.text = volume.toString() } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private EditText edtWidth, edtHeight, edtLength; private Button btnCalculate; private TextView tvResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtWidth = findViewById(R.id.edt_width); edtHeight = findViewById(R.id.edt_height); edtLength = findViewById(R.id.edt_length); btnCalculate = findViewById(R.id.btn_calculate); tvResult = findViewById(R.id.tv_result); btnCalculate.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_calculate) { String inputLength = edtLength.getText().toString().trim(); String inputWidth = edtWidth.getText().toString().trim(); String inputHeight = edtHeight.getText().toString().trim(); boolean isEmptyFields = false; if (TextUtils.isEmpty(inputLength)) { isEmptyFields = true; edtLength.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputWidth)) { isEmptyFields = true; edtWidth.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputHeight)) { isEmptyFields = true; edtHeight.setError("Field ini tidak boleh kosong"); } if (!isEmptyFields) { double volume = Double.parseDouble(inputLength) * Double.parseDouble(inputWidth) * Double.parseDouble(inputHeight); tvResult.setText(String.valueOf(volume)); } } } }
- Jalan kembali aplikasi Anda dengan memilih menu Run → Run ‘app’ atau shortcut Shift + F10. Cobalah langsung menekan tombol HITUNG tanpa mengisi EditText, maka aplikasi Anda tidak akan force close dan akan muncul peringatan bahwa "Field ini tidak boleh kosong".
- Apakah kita sudah selesai? Belum! Masih ada yang kurang. Ketika nilai volume sudah dihitung dan kemudian terjadi pergantian orientasi (portrait-landscape) pada peranti, maka hasil perhitungan tadi akan hilang.
Untuk mengatasinya, tambahkan metode onSaveInstanceState() pada MainActivitydan sesuaikan seperti berikut:
Kemudian tambahkan juga beberapa baris berikut pada baris terakhir metode onCreate.Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var edtWidth: EditText private lateinit var edtHeight: EditText private lateinit var edtLength: EditText private lateinit var btnCalculate: Button private lateinit var tvResult: TextView companion object { private const val STATE_RESULT = "state_result" } override fun onCreate(savedInstanceState: Bundle?) { ... } override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(STATE_RESULT, tvResult.text.toString()) } ... }
Catatan:
Karena onSaveInstanceState adalah class yang ada di superclass AppCompatActivity, Anda bisa membuat fungsi secara otomatis dengan hanya mengetikkan huruf onSave... dan pilih yang hanya memiliki satu parameter.Java public class MainActivity extends AppCompatActivity implements View.OnClickListener{ private EditText edtWidth; private EditText edtHeight; private EditText edtLength; private Button btnCalculate; private TextView tvResult; private static final String STATE_RESULT = "state_result"; @Override protected void onCreate(Bundle savedInstanceState) { ... } @Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putString(STATE_RESULT, tvResult.getText().toString()); } ... }
Catatan:
Karena onSaveInstanceState adalah class yang ada di superclass AppCompatActivity, Anda bisa membuat fungsi secara otomatis dengan hanya mengetikkan huruf onSave... dan pilih yang hanya memiliki satu parameter.Kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... if (savedInstanceState != null) { val result = savedInstanceState.getString(STATE_RESULT) tvResult.text = result } }
Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... if (savedInstanceState != null) { String result = savedInstanceState.getString(STATE_RESULT); tvResult.setText(result); } }
- Silakan jalankan kembali aplikasinya. Ulangi proses perhitungan seperti sebelumnya. Kemudian ganti orientasi peranti Anda. Jika sudah benar maka hasil perhitungan tidak akan hilang.
Bedah Kode
Pembahasan tentang layout xml
Layout merupakan user interface dari suatu activity. Layout dituliskan dalam format xml (extensible markup language).
xml version="1.0" encoding="utf-8"?>
Baris ini mengidentifikasi bahwa berkas ini berformat xml.
xmlns:android="http://schemas.android.com/apk/res/android"
Kode di atas menandakan namespace yang digunakan dalam keseluruhan berkas xml ini.
Macam View
Di sini kita menggunakan beberapa komponen user interface yang disebut view. Di antaranya:
- TextView : Komponen view untuk menampilkan teks ke layar
- EditText : Komponen view untuk memberikan input teks
- Button : Komponen view untuk melakukan sebuah aksi klik
- LinearLayout : Komponen view bertipe viewgroup yang menjadi parent dari semua sub komponen view (sub view) di dalamnya. Komponen ini bersifat sebagai kontainer untuk komponen lain dengan orientasi secara vertikal atau horizontal.
Cara membaca :
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/calculate" android:layout_marginBottom="16dp"/>
Komponen di atas adalah sebuah TextView. Perhatikan gambar di bawah ini. Warna ungu menandakan namespace yang digunakan; warna biru adalah atribut dari komponen dan warna hijau adalah nilai dari atribut. Penjelasannya seperti di bawah ini:
Berikut ini adalah beberapa format dalam pengisian value.
- android:<property_name>="@+id/view_id" untuk penulisan id
- android:<property_name>="<property_value>" untuk attribute biasa
- android:<property_name>="@<resource_type>/resource_id" untuk attribute yang memanggil value dari folder res, seperti string, color, dan dimens.
Sebagai contoh dari pengisian value dengan resource adalah @string/calculate. Value calculate berasal dari berkas strings.xml yang bisa Anda lihat dengan cara menekan dan tahan tombol Ctrl (atau command) + arahkan kursor ke atasnya dan kemudian klik sekali.
Penggunaan centralize resource value akan memudahkan Anda sewaktu mengembangkan aplikasi Android. Cara tersebut digunakan agar Anda tidak menulis nilai yang sama berulang-ulang.
Apa itu ‘@+id/’ ?
Salah satu contoh penerapan penggunaan @+id/ sebagai berikut:
<Button android:id="@+id/btn_calculate" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/calculate"/>
Penjelasannya sebagai berikut:
android:id="@+id/btn_calculate"
Jika kita memberikan id pada sebuah view maka kita telah memberikan identifier untuk view tersebut. Pemberian id ini dimaksudkan agar kita bisa melakukan manipulasi/pengendalian pada level logic di komponen seperti activity atau fragment.
Id di atas akan diciptakan di berkas R dan disimpan dalam bentuk hexa bertipe data integer public static final int btn_calculate=0x7f0b0057.
Acuan untuk menyusun tampilan pada relativelayout akan dibahas pada modul selanjutnya.
Ukuran View
Dalam menentukan tinggi dan lebar suatu View, terdapat beberapa alternatif value yang bisa digunakan seperti berikut.
- wrap_content: ukuran menyesuaikan dengan ukuran konten di dalamnya.
- match_parent: ukurang menyesuaikan dengan ukuran parent (View induknya). Apabila di paling luar, berarti mengikuti ukuran layar device-nya.
- fixed size: Anda bisa menentukan ukuran dengan nilai tetap dengan satuan dp.
Berikut adalah contoh ilustrasinya.
Padding dan Margin
Perhatikan attribute padding pada LinearLayout berikut.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" android:orientation="vertical">
Padding merupakan salah satu attribute untuk memberikan jarak antara satu komponen dengan komponen lain. Berikut adalah beberapa alternatif untuk memberikan jarak antar View.
- Padding : jarak dari isi ke tepi komponen (dalam).
- Margin : jarak dari tepi komponen ke komponen lain (luar).
Supaya mendapatkan gambaran terkait kedua attribute tersebut, perhatikan ilustrasi berikut.
Satuan Ukuran pada Android
Apabila pada ukuran dan padding ada dp, perhatikan attribute textSize pada kode berikut.
<TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="Hasil" android:textSize="24sp" android:textStyle="bold" />
Jadi, selain dp, ternyata juga ada satuan ukuran yang lain. Apa saja itu? Mari kita simak satu per satu.
sp (scale independent pixel)
Digunakan untuk ukuran teks, tetapi diskalakan berdasarkan preferensi ukuran font pengguna.dp (density independent pixel)
Digunakan untuk semuanya selain ukuran teks.- px
Sesuai dengan piksel sebenarnya di layar. Penggunaannya tidak disarankan karena dapat menghasilkan ukuran yang berbeda.
Supaya dapat memahami perbedaan dari penggunaan px, perhatikan ilustrasi berikut.
Perhatikan bahwa ketika menggunakan px, bisa menampilkan ukuran yang berbeda pada ukuran layar yang berbeda. Sebagai contoh di sini pada layar hdpi seperti ponsel dan xxhdpi pada tablet. Untuk itulah penggunaan px sebaiknya dihindari.
Pembahasan tentang Logika Kode
Kode logika dituliskan ke dalam kelas Java atau Koltin. Di sinilah semua aktifitas dari suatu aplikasi berjalan.
Activity
Kotlin |
class MainActivity : AppCompatActivity() |
Java |
public class MainActivity extends AppCompatActivity |
Menandakan bahwa kelas Java / Kotlin di atas merupakan sebuah activity karena inherit ke superclass bernama AppCompatActivity. AppCompatActivity merupakan kelas dasar yang mengatur fungsi dasar Activity supaya bisa tetap berjalan pada versi Android lama, seperti pengaturan tema dan app bar.
OnClickListener
Kotlin |
, View.OnClickListener |
Java |
implements View.OnClickListener |
Ini adalah listener yang kita implementasikan untuk memantau kejadian klik pada komponen tombol (button)
View
Kotlin |
private lateinit var edtWidth: EditText private lateinit var edtHeight: EditText private lateinit var edtLength: EditText private lateinit var btnCalculate: Button private lateinit var tvResult: TextView |
Java |
private EditText edtWidth; private EditText edtHeight; private EditText edtLength; private Button btnCalculate; private TextView tvResult; |
Kode di atas mendeklarasikan semua komponen view yang akan dimanipulasi. Kita deklarasikan secara global agar bisa dikenal di keseluruhan bagian kelas. Selain itu,
Selain itu, perhatikan juga bahwa untuk memanggil setiap komponen tersebut, di awal kode kita perlu menambahkan import seperti berikut.
import android.widget.Button import android.widget.EditText import android.widget.TextView ...
Untungnya dengan code completion, Anda tidak perlu menuliskan kode tersebut per satu karena sistem akan otomatis menambahkannya.
Berbeda jika Anda melakukan copy-paste tanpa menyertakan import, biasanya akan muncul tanda merah. Sebenarnya ada cara yang lebih mudah selain selain menggunakan ALT+Enter dan menambahkan import satu per satu, yaitu dengan menggunakan Auto Import. Untuk mengaktifkannya, bukan File → New Project Setup → Settings for New Projects... Buka Other Settings → Auto Import. Kemudia, pada bagian Java dan Kotlin, pastikan kotak Add unambiguous imports on the fly dan Optimize imports on the fly dalam keadaan tercentang. Simpan perubahan dan tutup halaman setting dengan menekan OK.
onCreate
Kotlin |
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) edtWidth = findViewById(R.id.edt_width) edtHeight = findViewById(R.id.edt_height) edtLength = findViewById(R.id.edt_length) btnCalculate = findViewById(R.id.btn_calculate) tvResult = findViewById(R.id.tv_result) btnCalculate.setOnClickListener(this) } |
Java |
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtWidth = findViewById(R.id.edt_width); edtHeight = findViewById(R.id.edt_height); edtLength = findViewById(R.id.edt_length); btnCalculate = findViewById(R.id.btn_calculate); tvResult = findViewById(R.id.tv_result); btnCalculate.setOnClickListener(this); } |
Metode onCreate() merupakan metode utama yang pertama kali dipanggil pada Activity. Anda bisa membayangkan fungsi ini seperti fungsi main() pada program Kotlin. Di sinilah kita dapat mengatur layout XML. Semua proses inisialisasi komponen yang digunakan akan dijalankan di sini. Pada metode ini kita menghubungkan semua variabel dengan komponen view dari XML agar dapat kita kelola interaksinya, seperti mengambil data, mengatur data, ataupun memantau aksi klik.
setContentView
Kotlin |
setContentView(R.layout.activity_main) |
Java |
setContentView(R.layout.activity_main); |
Maksud baris di atas adalah kelas MainActivity akan menampilkan tampilan yang berasal dari layout activity_main.xml. Biasanya sebuah Activity terhubung dengan sebuah XML juga.
Casting View
Kotlin |
edtWidth = findViewById(R.id.edt_width) |
Java |
edtWidth = findViewById(R.id.edt_width); |
Maksud dari baris di atas adalah obyek EditText edtWidth dihubungkan dengan komponen EditText ber-ID edt_width di layout activity_main.xml melalui metode findViewById().
setOnClickListener
Kotlin |
class MainActivity : AppCompatActivity(), View.OnClickListener { ... override fun onCreate(savedInstanceState: Bundle?) { ... btnCalculate.setOnClickListener(this) } override fun onClick(v: View?) { // aksi ketika tombol diklik } } |
Java |
public class MainActivity extends AppCompatActivity implements View.OnClickListener { ... @Override protected void onCreate(Bundle savedInstanceState) { ... btnCalculate.setOnClickListener(this); } @Override public void onClick(View v) { // aksi ketika tombol diklik } } |
Kita memasang event setOnClickListener untuk obyek btnCalculate sehingga sebuah aksi dapat dijalankan ketika obyek tersebut diklik. Keyword this merujuk pada obyek Activity saat ini yang telah mengimplementasikan listener OnClickListener sebelumnya. Sehingga ketika btnCalculate diklik, maka fungsi onClick akan dipanggil dan melakukan proses yang ada di dalamnya.
Selain menambahkan interface di class seperti cara di atas, Anda juga dapat menuliskan interface secara langsung seperti ini.
Kotlin |
class MainActivity : AppCompatActivity() { // tanpa implements View.OnClickListener ... override fun onCreate(savedInstanceState: Bundle?) { ... btnCalculate.setOnClickListener(View.OnClickListener { // aksi ketika tombol diklik }) } } |
Java |
public class MainActivity extends AppCompatActivity { // tanpa implements View.OnClickListener ... @Override protected void onCreate(Bundle savedInstanceState) { ... btnCalculate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // aksi ketika tombol diklik } }); } } |
Menariknya lagi, dengan support dari masing bahasa pemrograman, kita bisa menyingkat kode tersebut menjadi seperti ini.
Kotlin |
class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... btnCalculate.setOnClickListener { // tanpa paranthesis // aksi ketika tombol diklik } } } |
Java |
public class MainActivity extends AppCompatActivity { ... @Override protected void onCreate(Bundle savedInstanceState) { ... btnCalculate.setOnClickListener((v -> { // tanpa override // aksi ketika tombol diklik }); } } |
Mengambil value dari EditText
Kotlin |
val inputLength = edtLength.text.toString().trim() val inputWidth = edtWidth.text.toString().trim() val inputHeight = edtHeight.text.toString().trim() |
Java |
String inputLength = edtLength.getText().toString().trim(); String inputWidth = edtWidth.getText().toString().trim(); String inputHeight = edtHeight.getText().toString().trim(); |
Sintaks .text.toString() di atas berfungsi untuk mengambil isi dari sebuah EditText kemudian menyimpannya dalam sebuah variabel. Tambahan .trim() berfungsi untuk menghiraukan spasi jika ada, sehingga nilai yang didapat hanya berupa angka.
Cek inputan yang kosong
Kotlin |
var isEmptyFields = false if (inputLength.isEmpty()) { isEmptyFields = true edtLength.error = "Field ini tidak boleh kosong" } if (inputWidth.isEmpty()) { isEmptyFields = true edtWidth.error = "Field ini tidak boleh kosong" } if (inputHeight.isEmpty()) { isEmptyFields = true edtHeight.error = "Field ini tidak boleh kosong" } |
Java |
boolean isEmptyFields = false; if (TextUtils.isEmpty(inputLength)) { isEmptyFields = true; edtLength.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputWidth)) { isEmptyFields = true; edtWidth.setError("Field ini tidak boleh kosong"); } if (TextUtils.isEmpty(inputHeight)) { isEmptyFields = true; edtHeight.setError("Field ini tidak boleh kosong"); } |
Sintaks .isEmpty() berfungsi untuk mengecek apakah inputan dari Editext itu masih kosong. Jika iya, maka kita akan menampilkan pesan error dengan menggunakan .setError("Field ini tidak boleh kosong") dan mengganti variabel Boolean isEmptyField menjadi true supaya bisa lanjut ke proses selanjutnya.
Menampilkan data ke TextView
Kotlin |
if (!isEmptyFields) { val volume = inputLength.toDouble() * inputWidth.toDouble() * inputHeight.toDouble() tvResult.text = volume.toString() } Sintaks !isEmptyFields memiliki arti "jika semua inputan tidak kosong". Jika kondisi tersebut terpenuhi, maka langkah selanjutnya yaitu melakukan proses perhitungan. Karena yang didapat dari EditText berupa String maka Anda perlu mengkonversinya terlebih dahulu dengan cara toDouble(). Langkah terakhir yaitu menampikan hasil perhitungan pada TextView tvResult dengan menggunakan .text. Di sini dapat kita lihat bahwa kita perlu merubah datanya yang sebelumnya Double menjadi String dengan menggunakan toString() karena untuk menampilkan data dengan .text harus berupa String. |
Java |
if (!isEmptyFields) { double volume = Double.parseDouble(inputLength) * Double.parseDouble(inputWidth) * Double.parseDouble(inputHeight); tvResult.setText(String.valueOf(volume)); } Sintaks !isEmptyFields memiliki arti "jika semua inputan tidak kosong". Jika kondisi tersebut terpenuhi, maka langkah selanjutnya yaitu melakukan proses perhitungan. Karena yang didapat dari EditText berupa String maka Anda perlu mengkonversinya terlebih dahulu dengan menggunakan Double.parseDouble(). Langkah terakhir yaitu menampikan hasil perhitungan pada TextView tvResult dengan menggunakan .setText(). Di sini dapat kita lihat bahwa kita perlu merubah datanya yang sebelumnya Double menjadi String dengan menggunakan String.valueOf() karena untuk menampilkan data dengan setText() harus berupa String. |
Pembahasan SaveInstanceState
Kotlin |
override fun onSaveInstanceState(outState: Bundle) { super.onSaveInstanceState(outState) outState.putString(STATE_RESULT, tvResult.text.toString()) } |
Java |
@Override protected void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); outState.putString(STATE_RESULT, tvResult.getText().toString()); } |
Perhatikan metode onSaveInstanceState. Di dalam metode tersebut, hasil perhitungan yang ditampilkan pada tvResult dimasukkan pada bundle kemudian disimpan isinya. Untuk menyimpan data disini menggunakan konsep Key-Value, dengan STATE_RESULT sebagai key dan isi dari tvResult sebagai value. Fungsi onSaveInstanceState akan dipanggil secara otomatis sebelum sebuah Activity hancur. Di sini kita perlu menambahkan onSaveInstanceState karena ketika orientasi berubah, Activity tersebut akan di-destroy dan memanggil fungsi onCreate lagi, sehingga kita perlu menyimpan nilai hasil perhitungan tersebut supaya data tetap terjaga dan tidak hilang ketika orientasi berubah.
Kotlin |
if (savedInstanceState != null) { val result = savedInstanceState.getString(STATE_RESULT) tvResult.text = result } |
Java |
if (savedInstanceState != null){ String hasil = savedInstanceState.getString(STATE_RESULT); tvResult.setText(hasil); } |
Pada onCreate inilah kita menggunakan nilai bundle yang telah kita simpan sebelumnya pada onSaveInstanceState. Nilai tersebut kita dapatkan dengan menggunakan Key yang sama dengan saat menyimpan, yaitu STATE_RESULT. Kemudian kita isikan kembali pada tvResult.
Selamat! Anda telah berhasil membuat dan menjalankan latihan Android pertama di peranti atau emulator. Silakan lanjut ke codelab berikutnya.
Anda dapat mengunduh source code materi ini di tautan berikut:
Cara Membaca Dokumentasi
Mantap! Anda telah melalui latihan pertama dalam membuat aplikasi Android. Anda mulai memahami sedikit demi sedikit arti dari setiap kode dengan bantuan bedah kode yang ada di bagian bawah Codelab. Namun, mungkin Anda masih penasaran dari mana bisa mengetahui kegunaan dari kode-kode tersebut. Selain itu, method apa saja yang bisa dipakai di komponen tersebut? Misalnya di komponen Button terdapat method setOnClickListener. Lalu apa lagi method yang lainnya? Jawabannya ada di Documentation!
Setiap framework biasanya memiliki dokumentasi masing-masing. Untuk framework Android, Anda bisa melihatnya di https://developer.android.com/docs. Di sana Anda bisa membaca dokumentasi penggunaan masing-masing komponen, contoh kode, panduan tutorial, dan juga best practice dalam pengembangan aplikasi.
Sebagai contoh pada aplikasi yang dibuat sebelumnya, Anda menggunakan komponen Button. Dengan menggunakan fitur search dan menuliskan "Button", maka Anda akan menjumpai halaman berikut: https://developer.android.com/reference/android/widget/Button.html
Di dalam halaman tersebut terdapat keterangan bagaimana cara menampilkan Button di layout XML. Kemudian bagaimana cara menambahkan aksi ketika sebuah Button diklik. Ada juga keterangan lainnya, seperti Constructor apa saja yang bisa digunakan untuk membuat Button sendiri (CustomView).
Selain membaca di halaman dokumentasi, Anda juga dapat membaca langsung dokumentasi suatu komponen melalui Android Studio. Caranya yaitu dengan menekan Ctrl+Q pada kode yang ingin dilihat dokumentasinya. Hasilnya nanti seperti gambar di bawah ini:
Selain dari sisi penggunaan suatu komponen misal Button, Anda juga dapat melihat panduan penggunaan Button dari sisi User Interface (UI) di https://developer.android.com/guide/topics/ui/controls/button.
Sudah paham? Jika sudah, Anda juga bisa menerapkan cara yang sama untuk komponen atau kode lainnya. Namun perhatikan bahwa Anda tak perlu membaca semua documentation satu per satu untuk mengetahui semua tentang Android. Itu ide yang buruk. Cukup cari yang sedang Anda butuhkan saja ya!
Rangkuman Activity
- Activity merupakan komponen penting Android yang berfungsi untuk menampilkan user interface ke layar pengguna dan mengelola interaksi yang ada di dalamnya.
- Setiap Activity harus terdaftar di AndroidManifest.xml supaya tidak terjadi error.
- Lifecycle merupakan urutan state yang menunjukkan posisi proses aplikasi mulai dari Activity diciptakan sampai dihancurkan. Berikut adalah lifecycle dari sebuah Activity.
- Anda dapat menambahkan kode pada setiap setiap state lifecycle dengan override fungsi yang ada pada Activity.
- Perhatikan bahwa dalam penulisan kode XML, ada dua cara dalam penulisan tag seperti berikut.
- Self-closing tag: tag diawali dengan < dan diakhiri dengan />. Biasanya digunakan untuk View tanpa isi.
- Opening tag dan closing tag: opening tag diawali dengan < dan diakhiri dengan > saja. Sebagai gantinya, ada closing tag dengan format </NamaView>. Biasanya digunakan untuk layout yang menampung View lain di dalamnya.
- DI dalam sebuah tag View, Anda bisa mengubah beberapa attribute dengan beberapa format berikut.
- android:<property_name>="@+id/view_id" untuk penulisan id.
- android:<property_name>="<property_value>" untuk attribute biasa.
- android:<property_name>="@<resource_type>/resource_id" untuk attribute yang memanggil value dari folder res, seperti string, color, dan dimens.
- Penulisan teks secara langsung (hardcoded) merupakan praktik yang kurang baik karena seharusnya kita menuliskan semua teks pada berkas res/values/strings.xml dan setelah itu baru memanggilnya.
- Dalam menentukan tinggi dan lebar suatu View, terdapat beberapa alternatif value yang bisa digunakan seperti berikut.
- wrap_content: ukuran menyesuaikan dengan ukuran konten di dalamnya.
- match_parent: ukurang menyesuaikan dengan ukuran parent (View induknya). Apabila di paling luar, berarti mengikuti ukuran layar device-nya.
- fixed size: Anda bisa menentukan ukuran dengan nilai tetap dengan satuan dp.
- Berikut beberapa alternatif untuk memberikan jarak antar View.
- Padding: jarak dari isi ke tepi komponen (dalam).
- Margin: jarak dari tepi komponen ke komponen lain (luar).
- Berikut beberapa satuan ukuran yang bisa Anda gunakan dalam mendesain menggunakan XML.
- sp (scale independent pixel): digunakan untuk ukuran teks, tetapi diskalakan berdasarkan preferensi ukuran font pengguna.
- dp (density independent pixel): digunakan untuk semuanya selain ukuran teks.
- px: ukuran piksel sebenarnya di layar. Penggunaan px tidak disarankan karena dapat menghasilkan ukuran yang berbeda.
- onCreate() merupakan fungsi yang pertama kali dipanggil ketika membuka sebuah Activity.
- setContentView digunakan untuk menampilkan XML pada sebuah Activity.
- findViewById digunakan untuk menginisialisasi variabel dengan komponen View yang ada di XML sesuai dengan id-nya.
- setOnClickListener digunakan untuk melakukan aksi tertentu ketika suatu komponen ditekan.
- Untuk mengambil suatu teks dari EditText, Anda bisa menggunakan fungsi getText().toString() pada Java atau text.toString pada Kotlin.
- Untuk mengatur teks suatu TextView, Anda bisa menggunakan fungsi setText pada Java dan .text pada Kotlin).
- onSaveInstanceState digunakan untuk mempertahankan data ketika terjadi configuration change.
- Configuration change terjadi karena perubahan yang signifikan pada aplikasi sehingga akan membuat Activity dihancurkan dan dibuat lagi. Contohnya seperti perubahan orientasi, perubahan bahasa, dan ukuran layar.
Teori Intent
Intent adalah mekanisme untuk melakukan sebuah action dan komunikasi antar komponen aplikasi misal Activity, Service, dan Broadcast Receiver. Ada tiga penggunaan umum intent dalam aplikasi Android yaitu:
- Memindahkan satu activity ke activity lain dengan atau tidak membawa data.
- Menjalankan background service, misalnya melakukan sinkronisasi ke server dan menjalankan proses berulang (periodic/scheduler task).
- Mengirimkan obyek broadcast ke aplikasi yang membutuhkan. Misal, ketika aplikasi membutuhkan proses menjalankan sebuah background service setiap kali aplikasi selesai melakukan booting. Aplikasi harus bisa menerima obyek broadcast yang dikirimkan oleh sistem Android untuk event booting tersebut.
Intent memiliki dua bentuk yaitu:
- Explicit Intent
Adalah tipe Intent yang digunakan untuk menjalankan komponen lain dengan tujuan yang sudah jelas atau eksplisit. Umumnya Intent ini digunakan untuk berpindah ke Activity lain pada satu aplikasi. Misalnya dari MainActivity menuju ke DetailActivity.
Explicit intent bekerja dengan memanfaatkan context dari Activity asal dan nama Activity yang dituju. Berikut adalah contoh kode dari gambaran Explicit Intent di atas:
Dengan memanggil fungsi startActivity berisi Intent, aplikasi akan langsung membuka Activity tersebut tanpa memberikan opsi lain.Kotlin val moveIntent = Intent(this@MainActivity, DetailActivity::class.java) startActivity(moveIntent)
Java Intent moveIntent = new Intent(MainActivity.this, DetailActivity.class); startActivity(moveIntent);
- Implicit Intent
Adalah tipe intent yang tidak memerlukan detail nama kelas yang ingin diaktifkan. Model ini memungkinkan komponen dari aplikasi lain bisa merespon request intent yang dijalankan.
Penggunaan tipe Intent ini umumnya diperuntukan untuk menjalankan fitur/fungsi dari komponen aplikasi lain. Contohnya ketika kita membutuhkan fitur untuk mengambil foto. Daripada membuat sendiri fungsi kamera, lebih baik kita menyerahkan proses tersebut pada aplikasi kamera bawaan dari peranti atau aplikasi kamera lain yang telah terinstal sebelumnya di peranti.
Hal yang sama misalnya ketika kita membutuhkan fungsi berbagi konten. Kita bisa memanfaatkan intent untuk menampilkan aplikasi mana saja yang bisa menangani fitur tersebut.
Implementasi implicit intent ini akan sangat memudahkan bagi pengembang agar tetap fokus pada proses bisnis inti dari aplikasi yang dikembangkan.
Lalu mengapa disebut Implicit Intent? Hal ini karena tujuannya masih belum jelas (implicit), misalnya Anda ingin membuka gallery. Maka pilihannya yaitu Anda bisa menggunakan default gallery atau menggunakan Google Photos. Jika ada aplikasi lainnya yang bisa menangani aksi ini, maka aplikasi itu pun akan muncul.Berikut adalah contoh kode dari gambaran Implicit Intent di atas:
Kotlin private val launcherIntentGallery = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> } val intent = Intent(Intent.ACTION_GET_CONTENT) intent.type = "image/*" launcherIntentGallery.launch(Intent.createChooser(intent, "Choose a Picture"))
Java ActivityResultLauncher<Intent> launcherIntentGallery = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() { @Override public void onActivityResult(ActivityResult result) { } }); Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); launcherIntentGallery.launch(Intent.createChooser(intent, "Choose a Picture"));
Baca dan pahami materi pada link berikut ini:
Latihan Explicit Intent
Tujuan
Codelab ini menitikberatkan pada implementasi intent untuk melakukan perpindahan dari Activity ke Activity lain, dengan atau tidak membawa data. Beberapa bagian dari codelab ini akan menjawab beberapa pertanyaan umum dalam pengembangan aplikasi Android sebagai berikut:
- Bagaimana berpindah dari satu Activity ke Activity lain?
- Bagaimana berpindah dari satu Activity ke Activity lain dengan membawa data?
- Single value dari suatu variabel.
- Obyek model dengan menggunakan Parcelable.
- Menjalankan komponen di aplikasi lain untuk keperluan membuka browser atau melakukan pemanggilan melalui aplikasi telepon bawaan?
- Mengirimkan hasil nilai balik melalui Intent.
Codelab selanjutnya adalah dengan membuat aplikasi yang dapat menerapakan kegunaan intent. Seperti ini tampilannya:
Alur Latihan
Berikut alur yang akan kita pelajari dalam latihan ini:
- Berpindah antar Activity menggunakan Explicit Intent.
- Mengirim data pada Intent menggunakan putExtra.
- Mengirim banyak data pada Intent menggunakan Parcelable.
- Berpindah antar aplikasi menggunakan Implicit Intent.
- Mendapatkan hasil dari Activity tujuan menggunakan registerForActivityResult.
Codelab Explicit Intent
Ikuti alur berikut untuk mengerjakan latihan ini:
- Buat Project baru di Android Studio dengan kriteria sebagai berikut:
Nama Project MyIntentApp Target & Minimum Target SDK Phone and Tablet, API level 21 Tipe Activity Empty Activity Activity Name MainActivity Use AndroidX artifacts True Language Kotlin / Java - Selanjutnya kita akan membangun antarmuka (interface) seperti ini:
- Kondisikan activity_main.xml menjadi seperti ini:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/btn_move_activity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_activity" /> </LinearLayout>
Tambahkan juga resource string-nya. Tambahkan semua string yang akan digunakan di project ini. Buka berkas strings.xmldan tambahkan kode berikut ini:<resources> <string name="app_name">MyIntentApp</string> <string name="move_activity">Pindah Activity</string> <string name="move_with_data">Pindah Activity dengan Data</string> <string name="move_with_object">Pindah Activity dengan Object</string> <string name="dial_number">Dial a Number</string> <string name="move_with_result">Pindah Activity untuk Result</string> <string name="result_from_activity">Hasil dari Activity</string> <string name="choose_number">Pilih angka yang kamu suka</string> <string name="_50">50</string> <string name="_100">100</string> <string name="_150">150</string> <string name="_200">200</string> <string name="choose">Pilih</string> <string name="data_received">Data Diterima</string> <string name="object_received">Object Diterima</string> <string name="this_is_moveactivity">Ini MoveActivity</string> </resources>
- Kemudian masuk ke MainActivity, tambahkan beberapa baris kode yang berfungsi untuk meperkenalkan button yang sudah ditambahkan di layout seperti ini:
Kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val btnMoveActivity: Button = findViewById(R.id.btn_move_activity) }
Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnMoveActivity = findViewById(R.id.btn_move_activity); }
- Lalu tambahkan beberapa baris yang berfungsi untuk menambahkan event onClick pada button btnMoveActivityseperti ini:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val btnMoveActivity: Button = findViewById(R.id.btn_move_activity) btnMoveActivity.setOnClickListener(this) } override fun onClick(v: View?) { when (v?.id) { R.id.btn_move_activity -> { } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnMoveActivity = findViewById(R.id.btn_move_activity); btnMoveActivity.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { } } }
- Button btnMoveActivity akan memiliki fungsi untuk berpindah Activity ke Activity lain. Sekarang kita buat Activity baru dengan cara sebagai berikut: klik kanan di package utama aplikasi package name → New → Activity → Empty Activity.
Lalu isikan MoveActivity pada dialog. Ketika sudah klik Finish.Catatan:
Untuk bahasa menyesuaikan dengan bahasa yang digunakan ketika pertama kali membuat project. - Untuk menandakan bahwa perpindahan Activity berhasil, silakan tambahkan satu TextView dan kondisikan activity_move.xml menjadi seperti berikut:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp" tools:context=".MoveActivity"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/this_is_moveactivity" /> </RelativeLayout>
- Setelah activity tujuan sudah berhasil diciptakan, sekarang saatnya menambahkan suatu intent pada method onClick() di MainActivity menjadi sebagai berikut:
Kotlin override fun onClick(v: View?) { when (v?.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } } }
Java @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } }
- Selesai! Langkah pertama untuk memindahkan satu activity ke activity lain sudah selesai, sekarang silakan jalankan aplikasi Anda dengan mengklik tombol pada menu bar. Seharusnya sekarang anda sudah bisa memindahkan activity dengan mengklik tombol Pindah Activity.
Bedah Kode
Register Activity
Kita telah belajar bagaimana membuat suatu activity baru. Di materi sebelumnya, syarat suatu activity haruslah terdaftar pada berkas AndroidManifest.xml. Karena menggunakan Android Studio, proses pendaftaran tersebut dilakukan secara otomatis.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.dicoding.picodiploma.myintentapp"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".MoveActivity" /> </application> </manifest>
Perhatikan bahwa MoveActivity sudah teregistrasi di AndroidManifest.xml. Sekarang sudah aman jika kita melakukan perpindahan activity dari MainActivity ke MoveActivity.
Jika kita lupa meregistrasikan Activity baru ke dalam berkas AndroidManifest.xml, maka akan terjadi eror seperti ini android.content.ActivityNotFoundException:Unable to find explicit activity class.
Intent Filter
Berikutnya, perhatikan pada kode dengan tag intent-filter yang ada di dalam AndroidManifest pada bagian MainActivity.
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
Intent-filter merupakan mekanisme untuk menentukan bagaimana suatu activity dijalankan oleh Android Runtime (ART) atau Dalvik Virtual Machine (DVM).
<action android:name="android.intent.action.MAIN" />
Baris di atas bermakna bahwa MainActivity menjadi entry point ke aplikasi.
<category android:name="android.intent.category.LAUNCHER" />
Kode di atas menandakan bahwa MainActivity akan dikategorikan sebagai activity launcher. Ini menandakan bahwa activity ini akan muncul di halaman home screen dalam bentuk launcher.
Pindah Activity
Selanjutnya, perhatikan kode berikut:
Kotlin |
val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) |
Java |
Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); |
Kita membuat suatu obyek intent dengan cara seperti di atas dengan memberikan context (this@MainActivity) dan kelas activity tujuan (MoveActivity::class.java) pada konstruktor kelas intent.
Untuk context dapat menggunakan this yang menandakan obyek kelas saat ini. Sedangkan kelas tujuan selalu diakhiri dengan menggunakan class.
Jika kita menggunakan code assistant (tekan ctrl + spasi) dari Android Studio, maka akan tampil rekomendasi (code hint) sebagai berikut:
Pada konteks di atas kita memilih packageContext: Context , cls: Class<*> sebagai inputan untuk nilai constructor intent.
Context adalah sebuah kelas yang digunakan untuk mengakses resource dari activity tersebut. anda akan sering membutuhkan context pada latihan-latihan selanjutnya, seperti saat mengambil data dari resource, mengakses SystemService, mendapatkan ApplicationInfo dan lain sebagainya.
Untuk lebih jelasnya anda bisa membaca artikel berikut:
Kemudian perhatikan baris kode berikutnya.
Kotlin |
val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) |
Java |
Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); |
Metode startActivity(moveIntent) akan menjalankan activity baru tanpa membawa data. Obyek intent yang diinputkan adalah obyek moveIntent yang ketika kode ini dijalankan maka akan membuka MoveActivity.
Pada modul ini kita telah berhasil memindahkan satu Activity ke Activity lain dengan tidak membawa data. Pada bagian selanjutnya kita akan membuat suatu intent yang di dalamnya akan membawa data ke Activity tujuan.
Latihan Mengirim Data pada Intent
Selanjutnya kita akan membuat sebuah Intent yang di dalamnya akan membawa data ke Activity tujuan. Siaap?
- Buka activity_main.xml, kemudian tambahkan satu tombol lagi di bawah tombol sebelumnya. Kode activity_main.xml akan jadi seperti ini:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> ...... <Button android:id="@+id/btn_move_activity_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_data" /> </LinearLayout>
- Setelah selesai dengan penambahan pada berkas activity_main.xml, maka lanjutkan dengan menambahkan beberapa baris berikut di MainActivity.
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... val btnMoveWithDataActivity: Button = findViewById(R.id.btn_move_activity_data) btnMoveWithDataActivity.setOnClickListener(this) } override fun onClick(v: View) { when (v.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } R.id.btn_move_activity_data -> { } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); .... Button btnMoveWithDataActivity = findViewById(R.id.btn_move_activity_data); btnMoveWithDataActivity.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } else if (v.getId() == R.id.btn_move_activity_data) { } } }
- Selanjutnya, buat Activity baru lagi seperti cara sebelumnya dan beri nama MoveWithDataActivity.
- Lalu pada layout activity_move_with_data.xmlkita tambahkan sebuah TextView untuk menampilkan data yang dikirimkan dari Activity asal.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <TextView android:id="@+id/tv_data_received" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/data_received" /> </RelativeLayout>
- Selanjutnya pada MoveWithDataActivity, kita inisialisasi TextView seperti berikut ini:
Kotlin class MoveWithDataActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_with_data) val tvDataReceived: TextView = findViewById(R.id.tv_data_received) } }
Java public class MoveWithDataActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_with_data); TextView tvDataReceived = findViewById(R.id.tv_data_received); } }
- Selanjutnya untuk menerima data dari Activity asal, ambil data dari Intent berdasarkan key dan tampilkan ke dalam TextView seperti berikut:
Kotlin class MoveWithDataActivity : AppCompatActivity() { companion object { const val EXTRA_AGE = "extra_age" const val EXTRA_NAME = "extra_name" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_with_data) val tvDataReceived: TextView = findViewById(R.id.tv_data_received) val name = intent.getStringExtra(EXTRA_NAME) val age = intent.getIntExtra(EXTRA_AGE, 0) val text = "Name : $name, Your Age : $age" tvDataReceived.text = text } }
Java public class MoveWithDataActivity extends AppCompatActivity { public static final String EXTRA_AGE = "extra_age"; public static final String EXTRA_NAME = "extra_name"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_with_data); TextView tvDataReceived = findViewById(R.id.tv_data_received); String name = getIntent().getStringExtra(EXTRA_NAME); int age = getIntent().getIntExtra(EXTRA_AGE, 0); String text = "Name : " + name + ", Your Age : " + age; tvDataReceived.setText(text); } }
- Dan sekarang saatnya kita menambahkan data pada Intent menggunakan putExtra di dalam MainActivityseperti baris yang ditebalkan.
Kotlin override fun onClick(v: View) { when (v.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } R.id.btn_move_activity_data -> { val moveWithDataIntent = Intent(this@MainActivity, MoveWithDataActivity::class.java) moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) startActivity(moveWithDataIntent) } } }
Java @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } else if (v.getId() == R.id.btn_move_activity_data) { Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); startActivity(moveWithDataIntent); } }
- Maka MainActivity akan jadi seperti ini:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val btnMoveActivity: Button = findViewById(R.id.btn_move_activity) btnMoveActivity.setOnClickListener(this) val btnMoveWithDataActivity: Button = findViewById(R.id.btn_move_activity_data) btnMoveWithDataActivity.setOnClickListener(this) } override fun onClick(v: View) { when (v.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } R.id.btn_move_activity_data -> { val moveWithDataIntent = Intent(this@MainActivity, MoveWithDataActivity::class.java) moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) startActivity(moveWithDataIntent) } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnMoveActivity = findViewById(R.id.btn_move_activity); btnMoveActivity.setOnClickListener(this); Button btnMoveWithDataActivity = findViewById(R.id.btn_move_activity_data); btnMoveWithDataActivity.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } else if (v.getId() == R.id.btn_move_activity_data) { Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); startActivity(moveWithDataIntent); } } }
- Silakan jalankan aplikasi Anda, kemudian coba klik pada tombol Pindah Activity dengan Data. Seharusnya Anda sudah bisa berpindah dari satu activity ke activity lain dengan membawa data.
Bedah Kode
Pada bagian sebelumnya Anda sudah mempelajari bagaimana berpindah dari satu activity ke activity lain dengan membawa data. Dan itu sangat penting karena ketika kita mengembangkan suatu aplikasi Android yang kompleks, akan ada banyak activity yang terlibat. Untuk memberikan pengalaman yang baik kepada pengguna, perpindahan Activity dengan data, sangat krusial.
Put Extra
Perhatikan kode di bawah ini:
Kotlin |
val moveWithDataIntent = Intent(this@MainActivity, MoveWithDataActivity::class.java) moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) startActivity(moveWithDataIntent) |
Java |
Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); startActivity(moveWithDataIntent); |
Perbedaan mendasar antara memindahkan Activity dengan membawa data atau tidak, adalah dengan menempatkan data ke obyek Intent pada baris ini.
Kotlin |
moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) |
Java |
moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); |
Kita memanfaatkan metode putExtra() untuk mengirimkan data bersamaan dengan obyek Intent. Sedangkan metode putExtra() itu sendiri merupakan metode yang menampung pasangan key-value dan memiliki beberapa pilihan tipe input seperti berikut:
Hampir semua tipe data untuk input value didukung oleh metode putExtra().
Kotlin |
moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") |
Java |
moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); |
Name | MoveWithDataActivity.EXTRA_NAME di mana EXTRA_NAME adalah variabel static bertipe data String dan bernilai extra_name pada MoveWithDataActivity. Penentuan nilai untuk key parameter untuk Intent adalah bebas, di sini kami merekomendasikan format terbaik yang biasa diimplementasikan. |
Value | DicodingAcademy Boy dengan tipe data string. |
Get Data
Setelah data dikirimkan, selanjutnya adalah mengambil data tersebut.
Di sini kita akan mengirimkan data bertipe string ke MoveWithDataActivity. Di dalam MoveWithdataActivity kita akan mengambil nilai data berdasarkan key yang dikirimkan dengan menggunakan metode getIntent().getStringExtra(key). Implementasinya sebagai berikut:
Kotlin |
val name = intent.getStringExtra(EXTRA_NAME) |
Java |
String name = getIntent().getStringExtra(EXTRA_NAME); |
Catatan : Key yang dikirimkan melalui putExtra() harus sama dengan key sewaktu mengambil nilai dari data yang dikirimkan melalui getStringExtra().
Dalam konteks di atas, key yang digunakan untuk mengirim dan mengambil nilai data adalah sama, yaitu EXTRA_NAME (yang bernilai “extra_name”). Nilai dari data yang dikirimkan melalui Intent disimpan ke dalam variabel name bertipe data string.
Fungsi dari EXTRA_NAME
sendiri yaitu sebagai Key. Seperti yang dijelaskan pada modul, untuk mengirim data dengan intent kita perlu mengirimnya dalam format putExtra(Key,Value). Dengan Key bertindak sebagai kunci yang dipakai untuk mengambil data di activity tujuannya, dan value adalah data yang akan dikirimkan. Jadi kalau bahasa gampangnya dalam bentuk dialog seperti ini:
Kode : "Aku mau ambil data nih?"
Sistem : "Data yang mana? Data kan banyak?"
Kode : "Yang key-nya 'EXTRA_NAME' sis (red: sistem)"
Sistem : "Ohh oke deh, ini data value-nya"
Begitu juga dengan variable age.
Kotlin |
val age = intent.getIntExtra(EXTRA_AGE, 0) |
Java |
int age = getIntent().getIntExtra(EXTRA_AGE, 0); |
Nilai dari variabel age yang bertipe data integer berasal dari getIntent().getIntExtra(Key, nilai default). Key yang digunakan untuk mengirimkan dan mengambil data adalah EXTRA_AGE (yang bernilai “extra_age”). Nilai default di sini merupakan nilai yang akan digunakan jika ternyata datanya kosong. Data kosong atau nilainya null bisa terjadi ketika datanya memang tidak ada, atau key-nya tidak sama.
Selamat! Anda telah mempelajari dua Explicit Intent dengan atau tidak membawa data.
Sebelumnya, mengirimkan data bernilai tunggal dari satu Activity ke Activity lain adalah hal yang mudah. Bernilai tunggal karena data yang dikirimkan berasal dari satu tipe data. Misalnya pada contoh di atas, pengiriman nilai data name dan age dilakukan secara individu. Yang satu bertipe data string dan yang lainnya bertipe data integer.
Sekarang pertanyaanya bagaimana Anda bisa mengirimkan banyak data sekaligus (misal 20 data atau 200 data) dari satu Activity ke Activity lain melalui intent? Apakah harus menambahkan putExtra satu per satu? Tenang, ada cara yang lebih mudah untuk melakukannya, yaitu dengan menggunakan kelas model yang terimplementasi parcelable. Penasaran bagaimana caranya? Yuk kita lanjut ke materi berikutnya!
Latihan Mengirim Data dengan Parcelable
Bagi yang belum mengenal apa itu Data Class, berikut penjelasan singkatnya. Data Class adalah sebuah kelas biasa yang tidak bergantung pada kelas lainnya. Class ini berfungsi untuk menyimpan model data (attribute) suatu objek. Class ini sama seperti POJO (Plain Old Java Object) pada Java yang memiliki properti/variabel dan metode setter-getter. Namun di Kotlin semua itu sudah tergenerate otomatis dan tidak terlihat, sehingga kode menjadi lebih ringkas. Sebagai contoh kelas Kotlin dan Java di bawah ini memiliki fungsi yang sama:
Kotlin |
data class MyBean(val someProperty: String) |
Java |
public class MyBean { private String someProperty; public MyBean(){ } public String getSomeProperty() { return someProperty; } public void setSomeProperty(String someProperty) { this.someProperty = someProperty; } } |
Lalu apa kegunaan Data Class? Data class akan membantu kita saat aplikasi semakin kompleks. Contohnya, data class berisi banyak field bisa kita gunakan untuk melakukan koneksi ke server untuk request API atau akses ke database lokal dengan SQLite. Untuk lebih lengkapnya Anda bisa membaca lebih lanjut tentang Data Class di sini.
Codelab Data Class
- Sebelum membuat objek parcelable, kita buat kelas Java POJO terlebih dahulu. Caranya, klik kanan pada package utama → New → Kotlin File/Class (untuk Kotlin) atau package utama → New → Java Class (untuk Java)
- Pada dialog isikan nama kelas dengan Person dan pilih Data Class (Kotlin) / Class (Java). Lalu klik Enter
- Setelah selesai terbentuk kelas Person, tambahkan parameter sesuai dengan data yang ingin kita tambahkan seperti ini:
Kotlin data class Person( val name: String?, val age: Int?, val email: String?, val city: String? )
Java public class Person{ private String name; private int age; private String email; private String city; public Person(){ } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } }
Untuk yang menggunakan Java, Anda tak perlu menulis satu demi satu metode setter-getter nya. Android Studio sudah menyediakan fasilitas generator untuk hal tersebut. Caranya, setelah Anda menentukan variabel apa saja yang akan digunakan, lakukan beberapa langkah sebagai berikut:
Klik kanan pada workspace, pilih Generate (Alt+Insert) → Pilih Getter and Setter.Pilih semua variabel dengan cara Ctrl+A pada windows atau Command+A pada mac.
Codelab Intent Explicit dengan Parcelable
Seperti yang diketahui bahwa di dalam Intent kita dapat menyisipkan data dengan tipe-tipe tertentu seperti String, Int, Double pada Intent. Tetapi tidak dengan tipe kompleks seperti objek, ArrayList, dll. Di sinilah peran besar Parcelable. Parcelable adalah suatu interface yang memungkinkan kita melakukan pengiriman satu objek sekaligus dari suatu Activity ke Activity lain. Objek yang diimplementasikan dengan Parcelable akan memudahkan Anda dalam mengirimkan data dari satu Activity ke Activity lainnya.
Kali ini Anda akan mengubah kelas Person untuk mengimplementasikan Parcelable.
- Implementasikan Parcelable di kelas Person.
Kotlin data class Person( val name: String?, val age: Int?, val email: String?, val city: String? ) : Parcelable
Java public class Person implements Parcelable { private String name; private int age; private String email; private String city; ... }
- Akan muncul tanda merah, namun jangan khawatir, Anda hanya perlu arahkan kursor ke bagian nama kelas Person, kemudian tekan Alt+Enter atau bisa juga klik pada lampu merah, kemudian pilih Add Parcelable Implementation.
- Sekarang Anda bisa menemukan beragam metode parcelable untuk kelas Person. Sekarang kelas Person sudah sah menjadi kelas Parcelable dan dapat dikirimkan ke Activity lain melalui Intent. Maka, kelas Person menjadi seperti ini:
Kotlin data class Person( val name: String?, val age: Int?, val email: String?, val city: String? ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readString(), parcel.readValue(Int::class.java.classLoader) as? Int, parcel.readString(), parcel.readString()) { } override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(name) parcel.writeValue(age) parcel.writeString(email) parcel.writeString(city) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<Person> { override fun createFromParcel(parcel: Parcel): Person { return Person(parcel) } override fun newArray(size: Int): Array<Person?> { return arrayOfNulls(size) } } }
Java public class Person implements Parcelable { private String name; private int age; private String email; private String city; public Person(){ } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } protected Person(Parcel in) { name = in.readString(); age = in.readInt(); email = in.readString(); city = in.readString(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(name); dest.writeInt(age); dest.writeString(email); dest.writeString(city); } @Override public int describeContents() { return 0; } public static final Creator<Person> CREATOR = new Creator<Person>() { @Override public Person createFromParcel(Parcel in) { return new Person(in); } @Override public Person[] newArray(int size) { return new Person[size]; } }; }
- Sekarang waktunya kita implementasikan pada Intent. Namun sebelumnya, tambahkan satu tombol lagi pada activity_main.xml sebagai berikut:
<Button android:id="@+id/btn_move_activity_object" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_object" />
Sehingga activity_main.xml kita menjadi sebagai berikut:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/btn_move_activity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_activity" /> <Button android:id="@+id/btn_move_activity_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_data" /> <Button android:id="@+id/btn_move_activity_object" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_object" /> </LinearLayout>
- Setelah selesai dengan layout, kini kita kenalkan Button tersebut di kelas MainActivity.
Kotlin ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... val btnMoveWithObject:Button = findViewById(R.id.btn_move_activity_object) btnMoveWithObject.setOnClickListener(this) } ...
Java ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... Button btnMoveWithObject = findViewById(R.id.btn_move_activity_object); btnMoveWithObject.setOnClickListener(this); } ...
- Buat Activity baru dengan nama MoveWithObjectActivity.
- Kemudian pada layout activity_move_with_object.xml tambahkan satu TextView untuk menampilkan data yang dikirimkan.
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="16dp"> <TextView android:id="@+id/tv_object_received" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/object_received" /> </RelativeLayout>
- Sekarang kita kenalkan TextView pada MoveWithObjectActivity sehingga menjadi sebagai berikut:
Kotlin class MoveWithObjectActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_with_object) val tvObject:TextView = findViewById(R.id.tv_object_received) } }
Java public class MoveWithObjectActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_with_object); TextView tvObject = findViewById(R.id.tv_object_received); } }
- Selanjutnya pada kelas MoveWithObjectActivity, kita gunakan getParcelableExtra untuk menerima objek dari Activity asal.
Kotlin class MoveWithObjectActivity : AppCompatActivity() { companion object { const val EXTRA_PERSON = "extra_person" } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_with_object) val tvObject:TextView = findViewById(R.id.tv_object_received) val person = if (Build.VERSION.SDK_INT >= 33) { intent.getParcelableExtra(EXTRA_PERSON, Person::class.java) } else { @Suppress("DEPRECATION") intent.getParcelableExtra(EXTRA_PERSON) } if (person != null) { val text = "Name : ${person.name.toString()},\nEmail : ${person.email},\nAge : ${person.age},\nLocation : ${person.city}" tvObject.text = text } } }
Java public class MoveWithObjectActivity extends AppCompatActivity { public static final String EXTRA_PERSON = "extra_person"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_with_object); TextView tvObject = findViewById(R.id.tv_object_received); Person person; if (android.os.Build.VERSION.SDK_INT >= 33) { person = getIntent().getParcelableExtra(EXTRA_PERSON, Person.class); } else { person = getIntent().getParcelableExtra(EXTRA_PERSON); } String text = "Name : " + person.getName() + ",\nEmail : " + person.getEmail() + ",\nAge : " + person.getAge() + ",\nLocation : " + person.getCity(); tvObject.setText(text); } }
- Setelah kita membuat Activity tujuan, kini saatnya tambahkan Intent beserta datanya pada bagian onClick di MainActivity.
Kotlin override fun onClick(v: View) { when (v.id) { ... R.id.btn_move_activity_object -> { val person = Person( "DicodingAcademy", 5, "academy@dicoding.com", "Bandung" ) val moveWithObjectIntent = Intent(this@MainActivity, MoveWithObjectActivity::class.java) moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person) startActivity(moveWithObjectIntent) } } }
Java @Override public void onClick(View v) { ... } else if (v.getId() == R.id.btn_move_activity_object) { Person person = new Person(); person.setName("DicodingAcademy"); person.setAge(5); person.setEmail("academy@dicoding.com"); person.setCity("Bandung"); Intent moveWithObjectIntent = new Intent(MainActivity.this, MoveWithObjectActivity.class); moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person); startActivity(moveWithObjectIntent); } }
- Sehingga kode MainActivity kita menjadi sebagai berikut:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val btnMoveActivity:Button = findViewById(R.id.btn_move_activity) btnMoveActivity.setOnClickListener(this) val btnMoveWithDataActivity:Button = findViewById(R.id.btn_move_activity_data) btnMoveWithDataActivity.setOnClickListener(this) val btnMoveWithObject:Button = findViewById(R.id.btn_move_activity_object) btnMoveWithObject.setOnClickListener(this) } override fun onClick(v: View) { when (v.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } R.id.btn_move_activity_data -> { val moveWithDataIntent = Intent(this@MainActivity, MoveWithDataActivity::class.java) moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) startActivity(moveWithDataIntent) } R.id.btn_move_activity_object -> { val person = Person( "DicodingAcademy", 5, "academy@dicoding.com", "Bandung" ) val moveWithObjectIntent = Intent(this@MainActivity, MoveWithObjectActivity::class.java) moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person) startActivity(moveWithObjectIntent) } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnMoveActivity = findViewById(R.id.btn_move_activity); btnMoveActivity.setOnClickListener(this); Button btnMoveWithDataActivity = findViewById(R.id.btn_move_activity_data); btnMoveWithDataActivity.setOnClickListener(this); Button btnMoveWithObject = findViewById(R.id.btn_move_activity_object); btnMoveWithObject.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } else if (v.getId() == R.id.btn_move_activity_data) { Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); startActivity(moveWithDataIntent); } else if (v.getId() == R.id.btn_move_activity_object) { Person person = new Person(); person.setName("DicodingAcademy"); person.setAge(5); person.setEmail("academy@dicoding.com"); person.setCity("Bandung"); Intent moveWithObjectIntent = new Intent(MainActivity.this, MoveWithObjectActivity.class); moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person); startActivity(moveWithObjectIntent); } } }
- Setelah semua komponen selesai dibuat, saatnya menjalankan kembali aplikasinya. Cobalah menakan tombol Pindah Activity dengan Object. Sekarang Anda sudah berhasil memindahkan satu objek secara utuh, Selamat!
Jika anda menggunakan bahasa Kotlin, ada fitur untuk membuat kelas Parcelable dengan lebih simpel dan tidak terlalu banyak kode hasil dari Add Implementation Parcelable, yaitu dengan menggunakan anotasi Parcelize. Untuk menambahkan parcelize Anda perlu mengikuti langkah-langkah berikut:
- Tambahkan kode berikut di build.gradle (module: app) di bawah apply plugin sebelum tag Android, sesuaikan juga urutan apply plugin di atasnya.
plugins{ id 'com.android.application' id 'kotlin-android' id 'kotlin-parcelize' } android { ... }
- Jangan lupa untuk unduh plugin dengan cara klik Sync Now yang muncul di pojok kanan atas ketika terjadi perubahan kode pada build.gradle.
- Kemudian Anda hanya perlu menambahkan anotasi @Parcelizedi atas kelas model yang sudah diimplementasikan Parcelable, maka hasil dan perbedaannya dapat Anda lihat pada kode berikut:
Keren kan? Dengan menggunakan Parcelize, Anda dapat menyederhanakan kode yang sebelumnya panjang menjadi lebih simpel dan bersih. Untuk tutorial yang selanjutnya kita akan terus menggunakan parcelize untuk mengimplementasi parcelable.Dengan Parcelize ... import kotlinx.parcelize.Parcelize @Parcelize data class Person( val name: String?, val age: Int?, val email: String?, val city: String? ) : Parcelable
Catatan:
Pastikan Anda menggunakan versi Kotlin terbaru (1.4.30 ke atas) supaya tidak terdapat errorTanpa Parcelize data class Person( val name: String?, val age: Int?, val email: String?, val city: String? ) : Parcelable { constructor(parcel: Parcel) : this( parcel.readString(), parcel.readValue(Int::class.java.classLoader) as? Int, parcel.readString(), parcel.readString()) { } override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(name) parcel.writeValue(age) parcel.writeString(email) parcel.writeString(city) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<Person> { override fun createFromParcel(parcel: Parcel): Person { return Person(parcel) } override fun newArray(size: Int): Array<Person?> { return arrayOfNulls(size) } } }
- Tambahkan kode berikut di build.gradle (module: app) di bawah apply plugin sebelum tag Android, sesuaikan juga urutan apply plugin di atasnya.
Bedah Kode
Akhirnya Anda sudah berhasil menerapkan 3 tipe perpindahan Activity secara eksplisit melalui intent. Sekarang, mari kita dalami penjelasannya satu per satu.
Put Parcelable
Kotlin |
val person = Person( "DicodingAcademy", 5, "academy@dicoding.com", "Bandung" ) |
Java |
Person person = new Person(); person.setName("DicodingAcademy"); person.setAge(5); person.setEmail("academy@dicoding.com"); person.setCity("Bandung"); |
Di atas kita menciptakan sebuah objek Person bernama person yang mana kelas tersebut adalah Parcelable. Kita atur semua data sesuai dengan propertinya. Kemudian kita akan mengirimkan objek tersebut ke MoveWithObjectActivity melalui sebuah Intent di bawah ini:
Kotlin |
val moveWithObjectIntent = Intent(this@MainActivity, MoveWithObjectActivity::class.java) moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person) startActivity(moveWithObjectIntent) |
Java |
Intent moveWithObjectIntent = new Intent(MainActivity.this, MoveWithObjectActivity.class); moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person); startActivity(moveWithObjectIntent); |
Metode putExtra() yang kita pilih saat ini adalah putExtra(String name, Parcelable value).
Get Parcelable
EXTRA_PERSON merupakan variabel static bertipe data string dan bernilai “extra_person”. Berfungsi sebagai key untuk mendapatkan value data yang dikirim
Selanjutnya pada MoveWithObjectActivity kita akan mengambil nilai seperti berikut:
Kotlin |
val person = if (Build.VERSION.SDK_INT >= 33) { intent.getParcelableExtra(EXTRA_PERSON, Person::class.java) } else { @Suppress("DEPRECATION") intent.getParcelableExtra(EXTRA_PERSON) } |
Java |
Person person; if (Build.VERSION.SDK_INT >= 33) { person = getIntent().getParcelableExtra(EXTRA_PERSON, Person.class); } else { person = getIntent().getParcelableExtra(EXTRA_PERSON); } |
Dan ini yang seru. Karena objek ini terdiri dari beragam tipe data pada atribut atau propertinya, kita hanya cukup membungkus itu semua ke dalam objek Parcelable. Melalui getIntent().getParcelableExtra(Key), Anda dapat mengambil nilai objek person yang sebelumnya telah dikirim hanya dengan satu variabel, bayangkan jika kita tidak menggunakan Parcelable, maka kita harus mengirim data satu per satu. Jika datanya sedikit mungkin tidak masalah tapi jika datanya puluhan, tentu akan merepotkan kan?
Selanjutnya kita dapat menampilkan data objek yang sudah diterima seperti ini:
Kotlin |
if (person != null) { val text = "Name : ${person.name.toString()},\nEmail : ${person.email},\nAge : ${person.age},\nLocation : ${person.city}" tvObject.text = text } |
Java |
String text = "Name : "+person.getName()+", Email : "+person.getEmail()+", Age : "+person.getAge() + ", Location : "+person.getCity(); tvObject.setText(text); |
Lalu, bagaimana jika kita ingin mengirimkan kumpulan objek Parcelable ke activity lain? Untuk mengirimkan kumpulan data, kita bisa memanfaatkan ArrayList dan metode putParcelableArrayListExtra.
Contoh kode ketika membuat Intent adalah seperti ini:
Kotlin |
var persons = ArrayList<Person>() ... moveWithObjectIntent.putParcelableArrayListExtra(KEY,persons) |
Java |
ArrayList<Person> persons = new ArrayList<>(); ... moveWithObjectIntent.putParcelableArrayListExtra(KEY,persons); |
Dan ketika mengambil kumpulan datanya, kita bisa menggunakan kode getParcelableArrayListExtra:
Kotlin |
intent.getParcelableArrayListExtra(EXTRA_PERSON, Person::class.java) |
Java |
ArrayList<Person> persons = getIntent().getParcelableArrayListExtra(KEY, Person.class); |
Parcelize (Khusus Kotlin)
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-parcelize'
Parcelize adalah fitur yang dapat digunakan untuk membuat implementasi Parcelable secara otomatis, untuk menggunakannya Anda harus menambahkan plugin di build.gradle(module: app) supaya bisa menggunakan fitur ini:
... import kotlinx.parcelize.Parcelize @Parcelize data class Person( val name: String?, val age: Int?, val email: String?, val city: String? ) : Parcelable
Anotasi @Parcelize di atas nama kelas, digunakan untuk memberi tanda bahwa kelas ini yang dipilih untuk menjadi parcelable. @Parcelize juga otomatis men-generate semua kode yang digunakan untuk implemetasi parcelize sebelumnya.
Selamat, Anda sudah bisa mengirim objek antar Activity! Selanjutnya, kita akan membuat sebuah contoh aplikasi dengan menggunakan jenis Intent yang lain, yakni Intent Implicit. Tetap semangat!
Latihan Implicit Intent
Anda sudah belajar bagaimana menggunakan Intent dengan tipe eksplisit. Sekarang saatnya Anda melanjutkan ke Intent dengan tipe implisit.
- Buka kembali activity_main.xml dan tambahkan satu tombol lagi di bagian bawah seperti berikut:
<Button android:id="@+id/btn_dial_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/dial_number" />
Sehingga berkas activity_main.xml kita sekarang menjadi:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/btn_move_activity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_activity" /> <Button android:id="@+id/btn_move_activity_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_data" /> <Button android:id="@+id/btn_move_activity_object" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_object" /> <Button android:id="@+id/btn_dial_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/dial_number" /> </LinearLayout>
- Sekarang, buka kembali MainActivity dan lanjutkan inisialisasi Button yang sudah ditambahkan
Kotlin override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... val btnDialPhone:Button = findViewById(R.id.btn_dial_number) btnDialPhone.setOnClickListener(this) }
Java @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... Button btnDialPhone = findViewById(R.id.btn_dial_number); btnDialPhone.setOnClickListener(this); }
- Selanjutnya, buat Implicit Intent dengan menambahkan action dan data yang dikirimkan.
Kotlin override fun onClick(v: View) { when (v.id) { ... R.id.btn_dial_number -> { val phoneNumber = "081210841382" val dialPhoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phoneNumber")) startActivity(dialPhoneIntent) } } }
Java @Override public void onClick(View v) { ... } else if (v.getId() == R.id.btn_dial_number) { String phoneNumber = "081210841382"; Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); startActivity(dialPhoneIntent); } }
- Sehingga kode keseluruhan untuk kelas MainActivity saat ini adalah:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val btnMoveActivity:Button = findViewById(R.id.btn_move_activity) btnMoveActivity.setOnClickListener(this) val btnMoveWithDataActivity:Button = findViewById(R.id.btn_move_activity_data) btnMoveWithDataActivity.setOnClickListener(this) val btnMoveWithObject:Button = findViewById(R.id.btn_move_activity_object) btnMoveWithObject.setOnClickListener(this) val btnDialPhone:Button = findViewById(R.id.btn_dial_number) btnDialPhone.setOnClickListener(this) } override fun onClick(v: View) { when (v.id) { R.id.btn_move_activity -> { val moveIntent = Intent(this@MainActivity, MoveActivity::class.java) startActivity(moveIntent) } R.id.btn_move_activity_data -> { val moveWithDataIntent = Intent(this@MainActivity, MoveWithDataActivity::class.java) moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy") moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5) startActivity(moveWithDataIntent) } R.id.btn_move_activity_object -> { val person = Person( "DicodingAcademy", 5, "academy@dicoding.com", "Bandung" ) val moveWithObjectIntent = Intent(this@MainActivity, MoveWithObjectActivity::class.java) moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person) startActivity(moveWithObjectIntent) } R.id.btn_dial_number -> { val phoneNumber = "081210841382" val dialPhoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phoneNumber")) startActivity(dialPhoneIntent) } } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btnMoveActivity = findViewById(R.id.btn_move_activity); btnMoveActivity.setOnClickListener(this); Button btnMoveWithDataActivity = findViewById(R.id.btn_move_activity_data); btnMoveWithDataActivity.setOnClickListener(this); Button btnMoveWithObject = findViewById(R.id.btn_move_activity_object); btnMoveWithObject.setOnClickListener(this); Button btnDialPhone = findViewById(R.id.btn_dial_number); btnDialPhone.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_move_activity) { Intent moveIntent = new Intent(MainActivity.this, MoveActivity.class); startActivity(moveIntent); } else if (v.getId() == R.id.btn_move_activity_data) { Intent moveWithDataIntent = new Intent(MainActivity.this, MoveWithDataActivity.class); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_NAME, "DicodingAcademy Boy"); moveWithDataIntent.putExtra(MoveWithDataActivity.EXTRA_AGE, 5); startActivity(moveWithDataIntent); } else if (v.getId() == R.id.btn_move_activity_object) { Person person = new Person(); person.setName("DicodingAcademy"); person.setAge(5); person.setEmail("academy@dicoding.com"); person.setCity("Bandung"); Intent moveWithObjectIntent = new Intent(MainActivity.this, MoveWithObjectActivity.class); moveWithObjectIntent.putExtra(MoveWithObjectActivity.EXTRA_PERSON, person); startActivity(moveWithObjectIntent); } else if (v.getId() == R.id.btn_dial_number) { String phoneNumber = "081210841382"; Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)); startActivity(dialPhoneIntent); } } }
- Setelah selesai, jalankanlah kembali aplikasi Anda. Yeay, Anda sudah bisa men-dial sebuah nomor telepon melalui aplikasi bawaan dari peranti Anda. Selamat!
Bedah Kode
Implicit Intent
Kotlin |
val phoneNumber = "081210841382" val dialPhoneIntent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:$phoneNumber")) startActivity(dialPhoneIntent) |
Java |
String phoneNumber = "081210841382"; Intent dialPhoneIntent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:"+phoneNumber)); startActivity(dialPhoneIntent); |
Baru saja kita mengimplementasikan penggunaan intent secara implicit untuk melakukan proses dial sebuah nomor telepon. Pada bagian Intent(Intent.ACTION_DIAL, Uri.parse("tel:"+phoneNumber)), kita menggunakan inputan Intent(ACTION, Uri) pada konstruktor sewaktu menciptakan objek Intent di mana:
- Action : Intent.ACTION_DIAL
- Uri : Uri.parse("tel:"+phoneNumber)
Variabel ACTION_DIAL menentukan intent filter dari aplikasi-aplikasi yang bisa menangani action tersebut. Di sini aplikasi yang memiliki kemampuan untuk komunikasi akan muncul pada opsi pilihan, sebagaimana ditampilkan ke pengguna.
Selain ACTION_DIAL, di Android sudah tersedia berbagai action yang tinggal didefinisikan sewaktu menciptakan objek Intent untuk mengakomodir berbagai tujuan.
Silakan cek tautan berikut untuk detailnya:
Apa itu URI (Uniform Resource Identifier)
Jika Anda belum memahami apa itu Uri, berikut penjelasan singkatnya:
Uri adalah sebuah untaian karakter yang digunakan untuk mengidentifikasi nama, sumber, atau layanan di internet sesuai dengan RFC 2396. Pada Uri.parse("tel:"+phoneNumber), kita melakukan parsing uri dari bentuk teks string menjadi sebuah objek uri dengan menggunakan metode static parse(String). Secara struktur ia terbagi menjadi:
Di mana tel adalah sebuah skema yang disepakati untuk sumber daya telepon dan phoneNumber adalah variabel string yang bernilai 081210841382. Skema lain dari Uri seperti geo untuk peta, http untuk browser sisanya bisa dilihat di halaman ini:
Proses Implicit Intent
Pada prosesnya, pemanggilan intent secara implicit akan berjalan sesuai dengan diagram di bawah ini:
- Aplikasi kita menjalankan intent untuk ACTION_DIAL melalui startActivity().
- Sistem Android akan melakukan seleksi terhadap semua aplikasi yang memiliki kemampuan untuk menangani action tersebut. Sistem Android akan menentukan aplikasi mana saja yang bisa memproses action berdasarkan intent filter yang telah ditentukan di berkas AndroidManifest.xml pada masing-masing aplikasi.
Sistem Android akan menampilkan opsi aplikasi-aplikasi mana saja yang bisa menangani action tersebut ke pengguna.
Pengguna memilih salah satu opsi aplikasi dan kemudian sistem Android akan me-routing ke activity pada aplikasi yang dipilih yang memiliki intent-filter untuk aksi ACTION_DIAL. - Aplikasi yang dipilih pun muncul di layar dengan nomor telepon yang sudah diatur.
Anda sudah mempelajari 3 buah intent secara explicit dan 1 buah intent secara implicit. Selamat!
Selanjutnya, kita akan membuat sebuah Intent yang didalamnya akan membawa data dengan ResultActivity. Tentu Anda penasaran, bukan? Yuk kita melangkah lag!
Latihan Mendapatkan Nilai Balik dari Intent
Pada modul ini kita akan membedah hubungan Activity dan Intent dalam menerima nilai balik. Kadang kala ketika kita menjalankan sebuah Activity dari Activity lain, kita mengharapkan ada nilai hasil balik dari Activity yang dijalankan ketika ia ditutup.
Contohnya kita memiliki Activity A yang menjalankan Activity B untuk melakukan sebuah proses. Lalu nilai hasil dari proses tersebut dikirimkan kembali ke Activity A sebelum Activity B ditutup dengan pemanggilan metode finish(). Itulah yang dinamakan sebuah Activity menerima nilai hasil balik dari Activity yang dia jalankan. Supaya lebih jelas, ayo kita lanjutkan lagi proses ngoding-nya.
- Sekarang untuk menerapkan konsep di atas, buat sebuah Activity baru dengan nama MoveForResultActivity.
- Kemudian pada activity_move_for_result.xml silakan kondisikan layout kita dengan 1 buah TextView, 1 buah RadioGroup, 4 buah RadioButton, dan 1 buah Button sebagai berikut:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/choose_number" /> <RadioGroup android:id="@+id/rg_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/rb_50" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/_50" /> <RadioButton android:id="@+id/rb_100" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/_100" /> <RadioButton android:id="@+id/rb_150" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/_150" /> <RadioButton android:id="@+id/rb_200" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/_200" /> </RadioGroup> <Button android:id="@+id/btn_choose" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/choose" /> </LinearLayout>
Tampilannya adalah seperti ini: - Setelah selesai, lanjutkan ke berkas MoveForResultActivity dengan mengenalkan komponen yang sudah ditambahkan.
Kotlin private lateinit var btnChoose: Button private lateinit var rgNumber: RadioGroup companion object { const val EXTRA_SELECTED_VALUE = "extra_selected_value" const val RESULT_CODE = 110 } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_for_result) btnChoose = findViewById(R.id.btn_choose) rgNumber = findViewById(R.id.rg_number) }
Java public class MoveForResultActivity extends AppCompatActivity { private Button btnChoose; private RadioGroup rgNumber; public static final String EXTRA_SELECTED_VALUE = "extra_selected_value"; public static final int RESULT_CODE = 110; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_for_result); btnChoose = findViewById(R.id.btn_choose); rgNumber = findViewById(R.id.rg_number); } }
- Kemudian kita beri aksi pada Button dengan menuliskan kode sebagai berikut:
Kotlin class MoveForResultActivity : AppCompatActivity(), View.OnClickListener { ... override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_move_for_result) btnChoose = findViewById(R.id.btn_choose) rgNumber = findViewById(R.id.rg_number) btnChoose.setOnClickListener(this) } override fun onClick(v: View) { if (v.id == R.id.btn_choose) { if (rgNumber.checkedRadioButtonId > 0) { var value = 0 when (rgNumber.checkedRadioButtonId) { R.id.rb_50 -> value = 50 R.id.rb_100 -> value = 100 R.id.rb_150 -> value = 150 R.id.rb_200 -> value = 200 } val resultIntent = Intent() resultIntent.putExtra(EXTRA_SELECTED_VALUE, value) setResult(RESULT_CODE, resultIntent) finish() } } } }
Java public class MoveForResultActivity extends AppCompatActivity implements View.OnClickListener { ... @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_move_for_result); ... btnChoose.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.btn_choose) { if (rgNumber.getCheckedRadioButtonId() != 0) { int value = 0; int id = rgNumber.getCheckedRadioButtonId(); if (id == R.id.rb_50) { value = 50; } else if (id == R.id.rb_100) { value = 100; } else if (id == R.id.rb_150) { value = 150; } else if (id == R.id.rb_200) { value = 200; } Intent resultIntent = new Intent(); resultIntent.putExtra(EXTRA_SELECTED_VALUE, value); setResult(RESULT_CODE, resultIntent); finish(); } } } }
- Pada activity_main.xml, tambahkan lagi satu Button dan satu TextView yang akan kita gunakan untuk menjalankan MoveForResultActivity seperti berikut:
<Button android:id="@+id/btn_move_for_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_result" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/result_from_activity" android:textSize="24sp" />
Sehingga layout activity_main.xml yang kita punya menjadi seperti ini:<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="16dp"> <Button android:id="@+id/btn_move_activity" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_activity" /> <Button android:id="@+id/btn_move_activity_data" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_data" /> <Button android:id="@+id/btn_move_activity_object" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_object" /> <Button android:id="@+id/btn_dial_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/dial_number" /> <Button android:id="@+id/btn_move_for_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="16dp" android:text="@string/move_with_result" /> <TextView android:id="@+id/tv_result" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="@string/result_from_activity" android:textSize="24sp" /> </LinearLayout>
- Setelah selesai, kita lanjut menginisialisasi TextView dan Button ke dalam berkas MainActivity.
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var tvResult: TextView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) ... val btnMoveForResult:Button = findViewById(R.id.btn_move_for_result) btnMoveForResult.setOnClickListener(this) tvResult = findViewById(R.id.tv_result) } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tvResult; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... Button btnMoveForResult = findViewById(R.id.btn_move_for_result); btnMoveForResult.setOnClickListener(this); tvResult = findViewById(R.id.tv_result); } ... }
- Selanjutnya kita buat launcher registerForActivityResult untuk menerima nilai balik. Alih-alih menggunakan startActivity, gunakan launcher tersebut untuk menjalankan Intent seperti berikut:
Kotlin class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var tvResult: TextView private val resultLauncher = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == MoveForResultActivity.RESULT_CODE && result.data != null) { val selectedValue = result.data?.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0) tvResult.text = "Hasil : $selectedValue" } } ... override fun onClick(v: View) { when (v.id) { ... R.id.btn_move_for_result -> { val moveForResultIntent = Intent(this@MainActivity, MoveForResultActivity::class.java) resultLauncher.launch(moveForResultIntent) } } }
Java public class MainActivity extends AppCompatActivity implements View.OnClickListener { private TextView tvResult; final ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == MoveForResultActivity.RESULT_CODE && result.getData() != null) { int selectedValue = result.getData().getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0); tvResult.setText(String.format("Hasil : %s", selectedValue)); } }); ... @Override public void onClick(View v) { ... } else if (v.getId() == R.id.btn_move_for_result) { Intent moveForResultIntent = new Intent(MainActivity.this, MoveForResultActivity.class); resultLauncher.launch(moveForResultIntent); } } }
- Setelah selesai, pastikan tidak ada bagian kode yang tertinggal. Jalankan kembali aplikasinya, dan coba Anda pilih tombol Pindah Activity untuk Result. Pilih angka yang Anda suka dan lihat hasilnya. Di MainActivity sudah ada angka yang tadi Anda pilih di objek TextView.
Bedah Kode
registerForActivityResult
Untuk membuat sebuah Activity yang dapat mengembalikan nilai, kita perlu membuat objek ActivityResultLauncher terlebih dahulu seperti ini:
Kotlin |
private val resultLauncher: ActivityResultLauncher<Intent> = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> ... } |
Java |
final ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { ... }); |
Anda perlu mendaftarkan jenis kembalian ke sistem dengan menggunakan kode registerForActivityResult dengan parameter ActivityResultContract berupa ActivityResultContract. Hal ini karena kita akan mendapatkan nilai kembalian setelah memanggil Activity baru. Perlu diketahui bahwa kita juga bisa mendapatkan nilai kembalian dari selain Activity, contohnya seperti foto dari galeri dengan mendefinisikan contract yang berbeda.
Selanjutnya, perbedaan mendasar antara perpindahan Activity untuk menghasilkan nilai balik dengan tidak, adalah pada metode untuk menjalankan object Intent-nya. Sebelumnya kita menggunakan startActivity(intent) untuk berpindah Activity. Nah, kali ini kita menggunakan launch(intent) dari object ActivityResultLauncher.
Kotlin |
val moveForResultIntent = Intent(this@MainActivity, MoveForResultActivity::class.java) resultLauncher.launch(moveForResultIntent) |
Java |
Intent moveForResultIntent = new Intent(MainActivity.this, MoveForResultActivity.class); resultLauncher.launch(moveForResultIntent); |
Mengatur dan Membaca Nilai Hasil
Pada MoveForResultActivity kita memilih satu angka, sebagai contoh angka 150. Kemudian ketika tombol ‘Pilih’ ditekan. Maka baris kode di bawah ini akan dijalankan.
Kotlin |
override fun onClick(v: View) { if (v.id == R.id.btn_choose) { if (rgNumber.checkedRadioButtonId > 0) { var value = 0 when (rgNumber.checkedRadioButtonId) { R.id.rb_50 -> value = 50 R.id.rb_100 -> value = 100 R.id.rb_150 -> value = 150 R.id.rb_200 -> value = 200 } val resultIntent = Intent() resultIntent.putExtra(EXTRA_SELECTED_VALUE, value) setResult(RESULT_CODE, resultIntent) finish() } } } |
Java |
@Override public void onClick(View v) { if (v.getId() == R.id.btn_choose) { if (rgNumber.getCheckedRadioButtonId() != 0) { int value = 0; int id = rgNumber.getCheckedRadioButtonId(); if (id == R.id.rb_50) { value = 50; } else if (id == R.id.rb_100) { value = 100; } else if (id == R.id.rb_150) { value = 150; } else if (id == R.id.rb_200) { value = 200; } Intent resultIntent = new Intent(); resultIntent.putExtra(EXTRA_SELECTED_VALUE, value); setResult(RESULT_CODE, resultIntent); finish(); } } } |
Pada kode di atas berfungsi untuk melakukan validasi nilai dari objek RadioButton yang dipilih. Bila ada nilai dari radiobutton, maka proses selanjutnya adalah menentukan objek RadioButton mana yang diklik berdasarkan nilai dari rgNumber.getCheckedRadioButtonId().
Mengapa kita tidak memeriksa langsung ke objek RadioButton? Karena kita menggunakan RadioGroup sebagai parent pada objek-objek RadioButton. Secara otomatis kita bisa mendapatkan mana objek RadioButton yang dipilih dengan rgNumber.getCheckedRadioButtonId().
<RadioGroup android:id="@+id/rg_number" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <RadioButton android:id="@+id/rb_50" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="50" android:layout_marginBottom="16dp"/> <RadioButton android:id="@+id/rb_100" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="100" android:layout_marginBottom="16dp"/> <RadioButton android:id="@+id/rb_150" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="150" android:layout_marginBottom="16dp"/> <RadioButton android:id="@+id/rb_200" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="200" android:layout_marginBottom="16dp"/> </RadioGroup>
Selanjutnya, ketika sudah didapatkan nilainya, baris ini akan dieksekusi:
Kotlin |
val resultIntent = Intent() resultIntent.putExtra(EXTRA_SELECTED_VALUE, value) setResult(RESULT_CODE, resultIntent) finish() |
Java |
Intent resultIntent = new Intent(); resultIntent.putExtra(EXTRA_SELECTED_VALUE, value); setResult(RESULT_CODE, resultIntent); finish(); |
Kita membuat sebuah Intent tanpa ada inputan apa pun di konstruktornya. Kemudian kita meletakkan variabel value ke dalam metode putExtra(Key, Value) dengan EXTRA_SELECTED_VALUE bertipekan static string dan bernilai “extra_selected_value”. Kemudian kita jadikan obyek resultIntent yang telah dibuat sebelumnya menjadi parameter dari setResult(RESULT_CODE, Intent).
Setelah itu, kita panggil method finish() untuk menutup MoveForResultActivity dan kembali ke Activity sebelumnya.
Ketika MoveForResultActivity telah tertutup sempurna, maka callback ActivityResultLauncher pada MainActivity akan dijalankan.
Kotlin |
private val resultLauncher: ActivityResultLauncher<Intent> = registerForActivityResult( ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == MoveForResultActivity.RESULT_CODE && result.data != null) { val selectedValue = result.data?.getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0) tvResult.text = "Hasil : $selectedValue" } } |
Java |
final ActivityResultLauncher<Intent> resultLauncher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == MoveForResultActivity.RESULT_CODE && result.getData() != null) { int selectedValue = result.getData().getIntExtra(MoveForResultActivity.EXTRA_SELECTED_VALUE, 0); tvResult.setText(String.format("Hasil : %s", selectedValue)); } }); |
Di sinilah MainActivity akan merespon terhadap nilai balik yang dikirimkan oleh MoveForResultActivity. Pada baris 4 di atas, dilakukan perbandingan apakah nilai resultCode sama yang dikirim oleh MoveForResultActivity. Selain itu, juga diperiksa, apakah data yang dikembalikan bernilai null atau tidak. Bila semua kondisi terpenuhi, data RadioButton yang dipilih akan ditampilkan di TextView tvResult.
Untuk lebih dalam lagi silakan pelajari materi pada tautan berikut:
Keren! Anda sudah belajar dasar-dasar penggunaan intent secara umum di proyek aplikasi Android. 4 intent secara eksplisit dan 1 secara implisit dengan satu di antaranya mencakup nilai balik dari Activity yang dijalankan.
Untuk mendalami materi intent, silakan meluncur ke tautan di bawah ini.
Untuk source code materi, silakan unduh di tautan berikut ini :