Mẹo viết code Kotlin cho Android developer không nên bỏ qua
Bài viết được sự cho phép của tác giả Sơn Dương
Kotlin hiện đã trở thành ngôn ngữ chính để lập trình ứng dụng Android, bên cạnh Java đã có phần già nua. Khi mới chuyển sang sử dụng Kotlin, chắc chắn bạn sẽ có đôi chút bỡ ngỡ. Nhưng mình đảm bảo, càng về sau, bạn càng cảm thấy khoái “anh chàng” Kotlin này.
Bài viết này, mình sẽ chia sẻ một số kinh nghiệm, kotlin tips trick để bạn viết code nhàn hơn, gọn gàng và nhanh hơn.
Cài đặt Kotlin
Hiện nay, bản Android Studio mới nhất đã tích hợp sẵn Kotlin, nên bạn không cần phải cài đặt thêm gì cả.
Mình chỉ lưu ý một vài điểm ch dự án của bạn.
Một là, để tạo mới một kotlin class, bạn chọn:
File > New > Kotlin file/class
- Hoặc
File > New > Kotlin activity
Phần đuôi mở rộng của các tệp kotlin là .kt
Hai là, Android Studio có một plugin hỗ trợ viết mã Kotlin rất tốt, bạn nên sử dụng nó cho dự án của mình. Mở build.gradle (module level), thêm dòng sau:
apply plugin: 'kotlin-android-extensions'
Nếu bạn tạo dự án Kotlin từ đầu bằng Android Studio thì chắc chắn trong build.gradle (application level) sẽ có đoạn code kiểu như sau:
buildscript { ext.kotlin_version = '1.0.2' repositories { jcenter() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } }
Ok, việc thiết lập để dự án sử dụng được Kotlin chỉ có vậy thôi.
Kotlin tips hay không nên bỏ qua
Dưới đây là một số thủ thuật/tính năng của Kotlin mà cá nhân mình thấy nó khá hay ho, đặc biệt là so với cách viết của Java.
1. Tính năng Static Layout Import
Trước đây, khi viết ứng dụng Android, không ai là không biết tới từ khóa: findViewById()
để tạo một reference từ code Java tới View trong layout XML. Nhiều khi, với layout có nhiều View cần phải reference, bạn nhìn code khai báo findViewById()
rất rất là nhiều.
Cũng có một số giải pháp khắc phục điều này, như sử dụng thư viện Butterknife, giúp tiết kiện thao tác khai báo đó. Đến Kotlin, nó còn cải tiến thêm một bước nữa, bằng cách cho phép import tất cả reference tới View chỉ bằng một lần import.
Chúng ta cùng ví dụ minh họa dưới đây:
<?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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="co.ikust.kotlintest.MainActivity"> <TextView android:id="@+id/helloWorldTextView" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </RelativeLayout>
Còn đây là đoạn mã trong Activity:
import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) helloWorldTextView.text = "Hello World!" } }
Như bạn thấy, chúng ta không cần phải khai báo findViewById()
gì hết, truy xuất thằng vào view thông qua ID của nó.
helloWorldTextView.text = "Hello World!"
Góc chú ý:
- Trong hàm
setContentView(R.layout.activity_main)
phải trỏ tới đúng layout nhé. Tránh hiện tượng “râu ông này cắm cằm bà kia“. Nếu bạn trỏ nhầm layout, tất nhiên là bạn gọi reference từ ID của View sẽ bị NULL, ứng dụng sẽ bị crash. - Riêng với Fragment, bạn nên khai báo
setContentView()
trong hàmonCreateView()
, sử dụng các reference để thiết lập UI trongonViewCreated()
.
Tham khảo việc làm Kotlin hấp dẫn trên TopDev
2. Viết POJO class trong Kotlin
So với tính năng static layout import, việc viết POJO (Plain Old Java Object) class bằng Kotlin còn ngắn gọn hơn nữa (so với Java).
Viết POJO class để làm gì? POJO class thực chất là các data class, mục đích để bạn định nghĩa dữ liệu kiểu Object, dùng để lưu dữ liệu vào DB, parse JSON…
Ví dụ, chúng ta có một JAVA class như sau:
public class User { private String firstName; private String lastName; public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } }
Với Kotlin, mã nguồn sẽ ngắn gọn hơn rất nhiều.
- Đầu tiên là bạn không cần phải viết từ khóa public, vì mặc định mọi thứ trong kotlin là public rồi.
- Không cần phải viết hàm get/set. Trong Kotlin, bạn truy xuất trực tiếp vào properties.
Do đó, với đoạn code Java trên, khi chuyển thành Kotlin thì chỉ còn như sau:
class User { var firstName: String? = null var lastName: String? = null }
Ngắn gọn mà vẫn dễ hiểu phải không!?
Còn rất nhiều điều hay ho khi bạn viết và khai báo POJO class, mời bạn đọc thêm chi tiết tại bài viết này: Khởi tạo Class trong Kotlin đơn giản và hiệu quả
3. Lambda Expressions
Lambda expressions là một tính năng được giới thiệu trong bản JAVA 8, được rất nhiều người ưu thích. Tuy nhiên, trên Android thì cũng mới chỉ hỗ trợ java 7, không biết bây giờ thì thế này. Điều đó đã khiến các lập trình viên đi tìm giải pháp thay thế, có thể kể tới Retrolambda
Nhưng nếu bạn sử dụng Kotlin thì lại đơn giản, bạn được hỗ trợ sẵn rồi, không cần cài gì thêm cả.
Về phần này, mình đã có một bài viết riêng để giải thích và hướng dẫn làm rất chi tiết, đừng bỏ qua nhé: Tìm hiểu Higher-Order Functions và Lambda trong Kotlin
4. Null-safety
Một trong những thứ khiến bạn ám ảnh và đau đầu nhất trong Java, đó chính là lỗi NullPointerException
. Khi chuyển sang Kotlin, với tính năng Null-safety, cơn đau đầu đó sẽ chấm dứt.
Với Kotlin, chỉ duy nhất những lỗi sau mới gây ra NullPointerException
:
- Bạn cố tình throw ra
NullPointerException
- Sử dụng toán tử !! (sẽ đề cập ở phần dưới bài viết)
- Nếu thuộc tính lateinit được truy xuất trong hàm khởi tạo trước khi nó được tạo. Lúc này bạn sẽ gặp lỗi
anUninitializedPropertyAccessException
Theo mặc định, tất cả các biến, thuộc tính của Object đều là non-null
(không thể giữ giá trị null) – Trừ khi chúng được khai báo là nullable.
Như đề cập ở trên, để khai báo một biến có thể null, bạn chỉ cần thêm dấu hỏi chấm vào sau kiểu dữ liệu. Ví dụ:
val number: Int? = null
Khi đã khai báo như trên mà bạn lại cố tình gọi hàm để tạo NullPointerException
như này:
val number: Int? = null number.toString()
Đoạn code sẽ không được complie vì không vượt qua được null check của chương trình. Nhưng nếu bạn thêm điều kiện check null thì lại OK
val number: Int? = null if(number != null) { number.toString(); }
Hoặc viết gọn hơn:
val number: Int? = null number?.toString()
Toán tử !!
Đôi khi, bạn muốn chương trình có thể bắn ra NullPointerException
như JAVA để khi test gặp lỗi mà biết mà sửa. Bạn có thể sử dụng toán tử !!
Đoạn code này sẽ bắn ra NullPointerException
:
val number: Int? = null number!!.toString()
Thuộc tính lateinit
Có một trường hợp khi sử dụng thuộc tính lateinit
mà có thể gây lỗi tương tự NullPointerException
.
Chúng ta cùng xem xét ví dụ sau:
class InitTest { lateinit var s: String; init { val len = this.s.length } }
Đoạn code khi compile sẽ không vấn đề gì cả. Nhưng khi chạy chương trình, ngay khi instance của đối tượng TestClass được, bạn sẽ gặp lỗi UninitializedPropertyAccessException
.
Nguyên nhân như mình đã đề cập ở trên, do bạn truy xuất vào thuộc tính s
trước khi nó được khởi tạo.
5. Hàm with()
Hàm with()
rất hữu ích khi bạn cần truy xuất vào nhiều thuộc tính của cùng một đối tượng. Nó giúp bạn đỡ phải gõ nhiều tên đối tượng để gọi thuộc tính.
with(helloWorldTextView) { text = "Hello World!" visibility = View.VISIBLE }
6. Chuyển một Object sang Map
Có một use case phổ biến đó là lưu trữ giá trị của các thuộc tính vào một mảng Map. Điều này bạn thường thấy với các ứng dụng làm việc với RESTful API khi cần parse JSON.
Sau đây là một ví dụ:
class User(val map: Map<String, Any?>) { val name: String by map val age: Int by map }
Khi sử dụng như sau:
val user = User(mapOf( "name" to "John Doe", "age" to 25 ))
7. Collections và Functional Operations
Với sự hỗ trợ của lambdas, các thao tác với Collection trong Kotlin được nâng lên tầm cao mới.
Đầu tiên, Kotlin có sự phân biệt giữa mutable collection và immutable collection.
Ví dụ: Có hai phiên bản của Iterable interface
- Iterable
- MutableIterable
Tương tự, cũng có hai phiên bản của List, Set và Map interfaces.
Ví dụ: toán tử any sẽ trả về giá trị true nếu có ít nhất một phần tử thỏa mãn điều kiện.
val list = listOf(1, 2, 3, 4, 5, 6) assertTrue(list.any { it % 2 == 0 })
Và còn rất nhiều tính năng khác nữa, các bạn có thể tham khảo thêm trong trang tài lệu chính thức của Kotlin.
Tạm kết
Trên đây chỉ là một số Kotlin tips, những tính năng hay ho mà Kotlin cung cấp. Nếu bạn càng làm việc nhiều với Kotlin, chắc chắn bạn sẽ ngày càng thêm yêu ngôn ngữ này.
Mình hi vọng bài viết này sẽ giúp ích cho các bạn trong dự án sắp tới.
Bài viết gốc được đăng tải tại vntalking.com
Có thể bạn quan tâm:
- 5 điều lập trình viên Java Developer chắc chắn sẽ thích ở Kotlin
- Android Jetpack là gì? Tại sao nên dùng Android Jetpack?
- Service trong Android là gì? Các loại service trong android
Xem thêm các việc làm công nghệ hấp dẫn trên TopDev
- M Mới ra trường không kinh nghiệm, sao làm BA?
- C Chuyển đổi SA key sang Workload Identity
- U Use Case Diagram và 5 sai lầm thường gặp
- K Kinh nghiệm xử lý câu lệnh điều kiện trong JavaScript
- D Dart là gì? Ứng dụng của ngôn ngữ lập trình Dart
- C Chuẩn Hóa CV, Nhận Ngay Phím Chất
- S So sánh MySQL và MongoDB: Nên chọn CSDL nào?
- D Dân BA có cần phải rành về kỹ thuật???
- C CSS Selector là gì? Cách sử dụng các loại CSS Selector phổ biến
- P Phân biệt Sketch, Wireframe, Mockup, và Prototype?