Skip to content
ExponaBLOG
MODERN ANDROID & KOTLIN · DAY 095 / 100

Android Studio productivity tips: lessons from production

Work faster every day.

Expona Admin7 min read

Android Studio productivity tips: lessons from production

Every keystroke and minute spent waiting for builds adds up when you're shipping features on a deadline. We've learned that mastering Android Studio's built-in tools separates teams that ship fast from teams that ship slowly, and the difference compounds over thousands of development hours. This article covers the productivity wins we've adopted from our experience in production environments—techniques that reduce friction in daily development work.

Live Edit for Compose

Compose development benefits enormously from Live Edit, a feature that recompiles and redeploys your composable functions without a full app restart. When you're iterating on UI layouts or styling, every second saved waiting for a rebuild is mental context regained.

To enable Live Edit, ensure you're running Android Studio Dolphin or later with a connected emulator or device running Android 12+. As you edit your composable code, you'll see changes reflected within 1–2 seconds rather than 30–60 seconds for a full build cycle.

kotlin
@Composable
fun ProductCard(product: Product) {
    Card(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp),
        elevation = CardDefaults.cardElevation(defaultElevation = 4.dp)
    ) {
        Column(modifier = Modifier.padding(16.dp)) {
            Text(
                text = product.name,
                style = MaterialTheme.typography.headlineSmall
            )
            Text(
                text = "$${product.price}",
                style = MaterialTheme.typography.bodyMedium,
                color = MaterialTheme.colorScheme.primary
            )
        }
    }
}

When you change the padding, elevation, or text styles in this function, Live Edit redeploys instantly. The productivity gain is particularly noticeable when refining spacing, colors, or typography—iterations that traditionally required a full rebuild. In practice, we've cut UI iteration cycles from minutes to seconds.

One constraint: Live Edit doesn't work for changes to function signatures, state initialization, or recomposable scope. If you add a new parameter or modify state logic, you'll still need a rebuild. But for the 80% of compose tweaks that are styling and layout, Live Edit is transformative.

Layout Inspector for recomposition counts

Performance problems in Compose often stem from excessive recompositions—functions rerunning when they shouldn't. The Layout Inspector in Android Studio makes recomposition counts visible, letting you spot inefficiencies before they reach production.

Open Layout Inspector via Tools > Layout Inspector, select your running app, and enable the "Recomposition Counts" option. You'll see each composable annotated with how many times it recomposed during the inspection window.

Consider a screen displaying a list of orders with a search bar:

kotlin
@Composable
fun OrderListScreen(viewModel: OrderViewModel) {
    var searchQuery by remember { mutableStateOf("") }
    val orders by viewModel.orders.collectAsState()
    
    Column {
        SearchBar(
            query = searchQuery,
            onQueryChange = { searchQuery = it }
        )
        LazyColumn {
            items(orders.filter { it.name.contains(searchQuery) }) { order ->
                OrderRow(order)
            }
        }
    }
}

@Composable
fun OrderRow(order: Order) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .padding(16.dp)
    ) {
        Text(order.id)
        Text(order.name)
        Text("$${order.total}")
    }
}

Without Layout Inspector, you might not realize that every keystroke in the search bar recomposes the entire list. With the inspector running, you'd see OrderRow recomposing far more than necessary. The fix is to use key() and stable data classes:

kotlin
LazyColumn {
    items(
        orders.filter { it.name.contains(searchQuery) },
        key = { it.id }
    ) { order ->
        OrderRow(order = order)
    }
}

data class Order(
    val id: String,
    val name: String,
    val total: Double
)

Now OrderRow only recomposes when that specific order's data changes, not when the search query changes. In production, we've used Layout Inspector to reduce recomposition counts by 10–50x on complex screens, improving frame rates and battery life.

Logcat filters for faster debugging

Logcat output becomes noise quickly—network logs, framework messages, and third-party library chatter drown out the signals you need. Custom filters let you focus on what matters without scrolling endlessly.

Open Logcat at the bottom of Android Studio and click the filter icon. Create a filter for your package and log tags:

Filter Type Example Value Use Case
Package com.mycompany.shop Show only logs from your app
Tag NetworkRequest|AuthError|Analytics (regex) Focus on specific subsystems
Level Warn or Error Catch problems early
Regex Pattern Exception|Crash|Failed Find failures across all tags

In a real scenario, imagine debugging an e-commerce checkout flow. You set a filter for your package and error level, then tag your logging calls strategically:

kotlin
class CheckoutRepository {
    suspend fun processPayment(amount: Double): Result {
        return try {
            val transaction = paymentService.charge(amount)
            Log.d("Checkout", "Payment processed: ${transaction.id}")
            Result.Success(transaction)
        } catch (e: Exception) {
            Log.e("CheckoutError", "Payment failed: ${e.message}", e)
            Result.Failure(e)
        }
    }
}

Now a filter for tag:Checkout|CheckoutError shows only payment-related logs, making failures immediate and unambiguous. Combine this with logcat's copy-to-clipboard feature and you've reduced investigation time from minutes to seconds.

Refactoring shortcuts for large codebases

Production codebases grow. Renaming classes, extracting functions, and moving files manually is error-prone and time-consuming. Android Studio's refactoring shortcuts scale your productivity with your codebase size.

Essential refactoring shortcuts:

  • Rename: Shift + F6 — Rename a class, function, variable, or package across all usages. It handles imports, string references in code comments, and more.
  • Extract Function: Ctrl+Alt+M (Windows/Linux) or Cmd+Alt+M (Mac) — Select lines and create a new function automatically.
  • Extract Variable: Ctrl+Alt+V or Cmd+Alt+V — Select an expression and create a variable for it.
  • Move: F6 — Move a class or function to another file or package; Android Studio updates all imports.
  • Inline: Ctrl+Alt+N or Cmd+Alt+N — Replace a function call with its body, useful for removing thin wrappers.

Example: You have a payment validation function that's grown messy and is used in three places:

kotlin
fun validatePaymentInput(cardNumber: String, cvv: String, amount: Double): Boolean {
    if (cardNumber.length < 13 || cardNumber.length > 19) return false
    if (cvv.length < 3 || cvv.length > 4) return false
    if (amount <= 0) return false
    if (!cardNumber.all { it.isDigit() }) return false
    if (!cvv.all { it.isDigit() }) return false
    return true
}

Use Extract Function to pull out card validation:

kotlin
fun validateCardNumber(cardNumber: String): Boolean {
    return cardNumber.length in 13..19 && cardNumber.all { it.isDigit() }
}

fun validateCvv(cvv: String): Boolean {
    return cvv.length in 3..4 && cvv.all { it.isDigit() }
}

fun validatePaymentInput(cardNumber: String, cvv: String, amount: Double): Boolean {
    if (!validateCardNumber(cardNumber)) return false
    if (!validateCvv(cvv)) return false
    if (amount <= 0) return false
    return true
}

Select the card validation lines, press Cmd+Alt+M, name the function, and Android Studio handles scope, imports, and parameter inference. What would take 2–3 minutes manually takes 10 seconds. Multiply this across a large refactor—renaming a core class or extracting a shared utility across 20 files—and you save hours.

Common mistakes

Relying on Live Edit for state-changing code: Live Edit works for UI, not for business logic or state initialization. If you modify a ViewModel or network call and expect Live Edit to refresh it, you'll get stale data. Always do a full rebuild when you change state management.

Ignoring Layout Inspector baseline: Teams often turn on Layout Inspector reactively—after a performance complaint. Establish a baseline recomposition count early in development, then track regressions. A composable that recomposes 50 times on first render is a red flag you won't catch without the tool.

Overfitting Logcat filters to one bug: A hyper-specific filter helps you debug today's issue but makes tomorrow's investigation harder. Use filters for subsystems and log levels, not for individual error messages.

Skipping refactoring shortcuts for "quick" changes: It's tempting to rename a variable manually across three files. Don't. Use Shift + F6. Manual edits introduce typos and missed references, especially under deadline pressure.

Key takeaways

  • Live Edit cuts Compose iteration cycles from 30–60 seconds to 1–2 seconds for layout and styling changes; use it for the majority of UI work.
  • Layout Inspector's recomposition counts identify performance bottlenecks before they reach production; check for unexpected recompositions early and often.
  • Custom Logcat filters reduce noise and surface the signals you need; tag your logs strategically to make debugging a few keystrokes away.
  • Refactoring shortcuts scale with your codebase; Shift + F6 for rename, Cmd+Alt+M for extract function, and F6 for move save hours over a production development cycle.
  • These tools compound over weeks and months—small productivity wins in isolation become massive efficiency gains when applied consistently across a team.
ShareXLinkedInReddit

Found this useful? Support the writing.

Buy me a coffee
Written by
Expona Admin
Site administrator

Comments

Loading comments…

Leave a comment

Comments are reviewed before they appear. Be kind and stay on topic.

Related articles