Android best coding practice - 2

Hi again

Chào mọi người.
Hôm nay xin được viết một vấn đề nhỏ nhỏ ( dành cho beginner giống em) liên quan đến việc gọi Activity từ 1 Activity khác.
Có lẽ Android developer chúng ta đã quá quen với việc gọi startActivity để di chuyển từ màn hình này sang màn hình khác rồi phải không?

Chi tiết

Theo như tài liệu của Android hướng dẫn , khi gọi DetailActivity từ MainActivity thường chúng ta sẽ viết thế này :

MainActivity.kt

val intent = Intent(this, OrderDetailActivity::class.java)
// Truyền data theo Itent có thể viết tại đây
startActivity(intent)

Như thế này hoàn toàn OK và không có bất cứ vấn đề gì cả.

Đối với newcomer mới join vào dự án thì việc những ngày đầu đọc code để hiểu logic cũng như làm quen với dự án sẽ mất kha khá thời gian .
Do vậy để làm giảm thời gian đó cũng như tạo ra 1 flow chung cho team cũng là vấn đề cả team cần nghĩ đến.

Cụ thể trong trường hợp này, dự án thực tế của mình cũng như đọc code github thì thấy họ rất ít khi viết code kiểu kia . Và đúng là khi viết như vậy code không đẹp, khó control , khó đọc cho new member join vào dự án.

Vấn đề

Như mọi người đều biết, trong 1project đối với 1 Activity sẽ có rất nhiều nơi gọi vào Activity đó chứ không chỉ có đường 1 chiều.
Ví dụ : Mình có 1 MainActivity từ đó mình có thể click button để Edit Order đã có hoặc Create new Order mới .
Nếu là mode edit thì mình sẽ phải truyền đi orderId còn nếu là mode new thì sẽ không truyền đi.

MainActivity.kt

fun toOrderDetail() {
    val intent = Intent(this, OrderDetailActivity::class.java)
    intent.putExtra(KEY_ORDER_ID, orderID)
    // Chỗ này theo như bài viết số 1 của mình, không nên để orderID là kiểu String
    // Mà nên cho thành sealed class để truyền theo Mode NEW hoặc EDIT
    // Tuy nhiên tạm thời bỏ qua vấn đề đó ở đây ( tất nhiên trong thực tế mình sẽ làm như vậy )
    startActivity(intent)
}

Đến đây mọi thứ vẫn hoàn toàn OK chả gây ra vấn đề gì khó hiểu cả.
Giờ lại nói đến cái cảm giác của new member khi mới vào dự án. Khi được anh leader giao cho 1 task nào đó, việc tìm hiểu code tất nhiên là quan trọng : Luồng di chuyển, logic blabla....

Thường thì mình sẽ tìm đến Activity đó ( OrderDetailActivity.kt ) rồi nhấn Cmd+B để xem nó được gọi từ những chỗ nào. Và nó sẽ ra dialog như hình trên. Sau khi confirm thì mình có thể đoán nó có 2 chỗ start cái Activity này.

Nhưng giờ mình thay đổi các viết về việc di chuyển Activity như sau

class OrderDetailActivity : AppCompatActivity() {

    companion object {

        const val KEY_ORDER_ID = "key_order_id"

        fun createIntent(context: Context): Intent {
            return Intent(context, OrderDetailActivity::class.java)
        }

        fun createIntentWithOrderId(context: Context, orderId: String): Intent {
            return Intent(context, OrderDetailActivity::class.java).apply {
                putExtra(KEY_ORDER_ID, orderId)
            }
        }

    }

    private val orderId by lazy {
        intent.getSerializableExtra(KEY_ORDER_ID) as String
    }
}

Với trường hợp như thế này , khi mình tìm luồng di chuyển, chỉ cần chọn vào method createIntent hoặc createIntentWithOrderid rồi nhấn Cmd+B là nó sẽ bay thẳng đến chỗ gọi. ( Mình sẽ tiết kiệm được thời gian cũng như không gây ra sai sót do phán đoán nhầm )

Tổng kết

Về cơ bản, đây là một vấn đề rất nhỏ và chắc chỉ dành cho newbie giống mình . Nhưng nếu trong team mình apply flow này từ đầu cũng sẽ là 1 cải thiện nhỏ:

  • Việc tạo Intent nên viết ở chính class sẽ di chuyển đến
  • Nếu có nhiều case di chuyển đến màn hình thì nên tách ra thành các method riêng ( ví dụ như : createIntentForUseCase1, createIntentForUseCase2 ....). Tất nhiên là nếu có thể tách thì nên tách.