DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Android Development Debug Tools Complete Guide — Layout Inspector/Profiler/LeakCanary

What You'll Learn

デバッグツール(Layout Inspector、Compose Profiler、LeakCanary、StrictMode、OkHttp Logging)を解説します。


Layout Inspector

Android StudioのLayout InspectorはCompose UIの階層構造をリアルタイムで表示します。

// デバッグビルドでInspector情報を有効化
android {
    buildTypes {
        debug {
            // Layout Inspectorが自動的にCompose情報を表示
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

LeakCanary

// build.gradle.kts
dependencies {
    debugImplementation("com.squareup.leakcanary:leakcanary-android:2.14")
}

// 設定不要!debugビルドで自動的にMemory Leak Detection
// リーク検出時に通知が表示される
Enter fullscreen mode Exit fullscreen mode

StrictMode

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            StrictMode.setThreadPolicy(
                StrictMode.ThreadPolicy.Builder()
                    .detectDiskReads()
                    .detectDiskWrites()
                    .detectNetwork()
                    .penaltyLog()
                    .build()
            )
            StrictMode.setVmPolicy(
                StrictMode.VmPolicy.Builder()
                    .detectLeakedClosableObjects()
                    .detectActivityLeaks()
                    .penaltyLog()
                    .build()
            )
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

OkHttp Logging

// build.gradle.kts
dependencies {
    debugImplementation("com.squareup.okhttp3:logging-interceptor:4.12.0")
}

@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
    @Provides
    @Singleton
    fun provideOkHttpClient(): OkHttpClient {
        return OkHttpClient.Builder().apply {
            if (BuildConfig.DEBUG) {
                addInterceptor(HttpLoggingInterceptor().apply {
                    level = HttpLoggingInterceptor.Level.BODY
                })
            }
        }.build()
    }
}
Enter fullscreen mode Exit fullscreen mode

Compose Recomposition Visualization

// デバッグ用Modifier
fun Modifier.recompositionCounter(): Modifier = composed {
    val count = remember { mutableIntStateOf(0) }
    count.intValue++

    if (BuildConfig.DEBUG) {
        drawWithContent {
            drawContent()
            drawRect(
                color = Color.Red.copy(alpha = 0.1f * minOf(count.intValue, 10)),
                size = size
            )
        }
    } else this
}

// 使用
Text("Hello", Modifier.recompositionCounter())
Enter fullscreen mode Exit fullscreen mode

Timber (Structured Logging)

dependencies {
    implementation("com.jakewharton.timber:timber:5.0.1")
}

class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()
        if (BuildConfig.DEBUG) {
            Timber.plant(Timber.DebugTree())
        } else {
            Timber.plant(CrashlyticsTree())
        }
    }
}

class CrashlyticsTree : Timber.Tree() {
    override fun log(priority: Int, tag: String?, message: String, t: Throwable?) {
        if (priority >= Log.ERROR) {
            Firebase.crashlytics.log(message)
            t?.let { Firebase.crashlytics.recordException(it) }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

ツール 用途
Layout Inspector UI Layout Confirmation
LeakCanary Memory Leak Detection
StrictMode Performance Violation Detection
HTTP Logging API Communication Debugging
Timber Structured Logging
  • debugImplementationでリリースに含めない
  • LeakCanaryは導入するだけで自動検出
  • StrictModeでメインスレッドの違反を検出
  • Timberでrelease/debugのログ出力を制御

8種類のAndroidAppTemplates(デバッグ設定済み)を公開しています。

Template ListGumroad

Related Articles:


Ready-Made Android App Templates

8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.

Browse templatesGumroad

Top comments (0)