Enhancing in Android Using Starter Pattern

Hardi Rachh
Make Android
Published in
4 min readDec 30, 2023
Photo by Sebastian Coman Photography on Unsplash

Introduction!!

Writing code for Android applications can be a straightforward task, but the key lies in producing high-quality code that not only distinguishes you as a developer but also minimizes runtime issues. In this blog post, we will dive into the use of the Starter Pattern to elevate the quality of your Android code, focusing specifically on money transfer activities involving a sender, a receiver, and a dedicated money transfer activity.

Identifying the Problem

To better understand the significance of the Starter Pattern, let’s consider a scenario involving three activities

SenderActivity, ReceiverActivity, and MoneyTransferActivity.

The constant values for these activities are declared in a class named MoneyConstants:

object MoneyConstants {
internal const val EXTRAS_MONEY = "extras_money"
internal const val SENDER_NAME = "sender_name"
internal const val RECEIVER_NAME = "receiver_name"
}

The SenderActivity open the MoneyTransferActivity on click of info button and passes the necessary details:

class SenderActivity : AppCompatActivity() {

private lateinit var binding: ActivitySenderBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySenderBinding.inflate(layoutInflater)
setContentView(binding.root)

binding.btnInfo.setOnClickListener {
val intent = Intent(this@SenderActivity, MoneyTransferActivity::class.java)
intent.putExtra(MoneyConstants.EXTRAS_MONEY , "100.0")
intent.putExtra(MoneyConstants.SENDER_NAME, "Hardy Shah")
intent.putExtra(MoneyConstants.RECEIVER_NAME, "Jana Smith")
startActivity(intent)
}
}
}

Similarly, the ReceiverActivity also open the MoneyTransferActivity on click of info button:

class ReceiverActivity : AppCompatActivity() {

private lateinit var bindng: ActivityReceiverBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
bindng= ActivityReceiverBinding.inflate(layoutInflater)
setContentView(bindng.root)

bindng.btnInfo.setOnClickListener{
val intent = Intent(this@ReceiverActivity, MoneyTransferActivity::class.java)
intent.putExtra(MoneyConstants.EXTRAS_MONEY , "100.0")
intent.putExtra(MoneyConstants.SENDER_NAME, "Hardy Shah")
intent.putExtra(MoneyConstants.RECEIVER_NAME, "Jana Smith")
startActivity(intent)
}
}
}

The Problem!

In a collaborative environment, issues may arise. For example, if you later decide to include additional details like a transaction id, the constant class would be updated:

object MoneyConstants {
internal const val EXTRAS_MONEY = "money_amount"
internal const val SENDER_NAME = "sender_name"
internal const val RECEIVER_NAME = "receiver_name"
internal const val TRANSACTION_ID = "transaction_id"
}

Since multiple developers are involved in this project, it’s possible that the ‘transaction id’ has been added in the SenderActivity but not in the ReceiverActivity. There won’t be any compile-time errors, but when you use the program, you may encounter bugs, especially in the ReceiverActivity. It’s crucial to address these issues during the development phase. Moreover, in larger projects, if there are more constants, you’ll need to include each one in the activity that invokes the MoneyTransferActivity.

The Solution — Leveraging the Starter Pattern: To mitigate such issues, we can employ the Starter Pattern. Let’s refactor the MoneyTransferActivity using this pattern,

class MoneyTransferActivity : AppCompatActivity() {
companion object {
internal const val EXTRAS_MONEY = "money_amount"
internal const val SENDER_NAME = "sender_name"
internal const val RECEIVER_NAME = "receiver_name"
internal const val TRANSACTION_ID = "transaction_id"

fun getStartIntent(context: Context, amount: String, senderName: String, receiverName: String): Intent {
val intent = Intent(context, MoneyTransferActivity::class.java)
intent.putExtra(EXTRAS_MONEY , amount)
intent.putExtra(SENDER_NAME, senderName)
intent.putExtra(RECEIVER_NAME, receiverName)
return intent
}
}

lateinit var binding: ActivityMoneyTransferInfoBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMoneyTransferInfoBinding.inflate(layoutInflater)
setContentView(binding.root)

val amount = intent.getStringExtra(EXTRAS_MONE)
val senderName = intent.getStringExtra(SENDER_NAME)
val receiverName = intent.getStringExtra(RECEIVER_NAME)
// Additional logic for handling transaction details
}
}

By using the Starter Pattern, we encapsulate the details within the MoneyTransferActivity and provide a clean interface for starting the activity. This not only reduces the chance of runtime errors but also enhances the code’s maintainability.

Using the refactored code, you can start the MoneyTransferActivity from the SenderActivity and ReceiverActivity as follows:

class SenderActivity : AppCompatActivity() {

private lateinit var binding: ActivitySenderBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySenderBinding.inflate(layoutInflater)
setContentView(binding.root)

//additional logic for get and set the values of money transfer
bindng.btnInfo.setOnClickListener{
startActivity(MoneyTransferActivity.getStartIntent(this@SenderActivity, "100.0, "Hardy Shah", "Jana Smith")
}
}
}
class ReceiverActivity : AppCompatActivity() {

private lateinit var bindng: ActivityReceiverBinding

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivitySenderBinding.inflate(layoutInflater)
setContentView(binding.root)

//additional logic for get and set the values of money transfer
bindng.btnInfo.setOnClickListener{
startActivity(MoneyTransferActivity.getStartIntent(this@ReceiverActivity, "100.0", "Hardy Shah", "Jana Smith")
}
}
}

Conclusion

Implementing the Starter Pattern is a valuable practice to elevate the quality of your Android code. By organizing constants and starting activities within the same class, you not only reduce runtime errors but also facilitate collaboration in a team environment. Start incorporating the Starter Pattern in your Android projects to produce robust and maintainable code.

Keep Learning :)

Thanks!!

Hardi Rachh

You can connect with me on → LinkedIn

--

--