Slide 1

Slide 1 text

Debugging as a Skill. D A A S @hi_man_shoe

Slide 2

Slide 2 text

Debugging. - Need for debugging? - Understanding basic aspect for Debugging. - Leveraging Android Studio for our use case. - Debugging Compose Code. @hi_man_shoe

Slide 3

Slide 3 text

What is debugging? @hi_man_shoe

Slide 4

Slide 4 text

The process of isolating and removing defects in software code. “ “ @hi_man_shoe

Slide 5

Slide 5 text

Debugging 101. fun testForPrintln() { val loggedInUser = getUser() println(loggedInUser) } @hi_man_shoe

Slide 6

Slide 6 text

Debugging 101. fun testForPrintln() { val loggedInUser = getUser() println(loggedInUser) } fun testForPrintln() { val loggedInUser = getUser() println(loggedInUser) } @hi_man_shoe

Slide 7

Slide 7 text

Debugging 101. fun testForPrintln() { val loggedInUser = getUser() println(loggedInUser) } fun testForPrintln() { val loggedInUser = getUser() println(loggedInUser) } Output @hi_man_shoe

Slide 8

Slide 8 text

Debugging 102. fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) } @hi_man_shoe

Slide 9

Slide 9 text

Debugging 102. fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) } fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) } Output

Slide 10

Slide 10 text

Debugging 102. fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) } fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) }

Slide 11

Slide 11 text

Debugging 102. fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) } fun testForLogger() { val loggedInUser = getUser() Log.d(TAG,loggedInUser.toString()) }

Slide 12

Slide 12 text

Types. - Debug (Log.e) - Verbose (Log.v) - Info (Log.i) - Warn (Log.w) - Error (Log.e) - WTF! (Log.wtf) : What a Terrible Failure @hi_man_shoe

Slide 13

Slide 13 text

Android Debugger : 201. - Debug the data loading/sequence in App - Can select the point to specifically check - Verify and move on! @hi_man_shoe

Slide 14

Slide 14 text

Android Debugger : 201. @hi_man_shoe

Slide 15

Slide 15 text

Android Debugger : 201. breakpoint @hi_man_shoe

Slide 16

Slide 16 text

Android Debugger : 201.

Slide 17

Slide 17 text

Android Debugger : 201. Re-run the app @hi_man_shoe

Slide 18

Slide 18 text

Android Debugger : 201. Stop the debugging fl ow @hi_man_shoe

Slide 19

Slide 19 text

Android Debugger : 201. Continue execution. @hi_man_shoe

Slide 20

Slide 20 text

Android Debugger : 201. Step into next line from breakpoint @hi_man_shoe

Slide 21

Slide 21 text

Android Debugger : 201. Step into the function @hi_man_shoe

Slide 22

Slide 22 text

Android Debugger : 201. Step out of the function @hi_man_shoe

Slide 23

Slide 23 text

Android Debugger : 201. Gives a list of all Breakpoints

Slide 24

Slide 24 text

Android Debugger : 201. Mutes all the breakpoints

Slide 25

Slide 25 text

Android Debugger : 201. @hi_man_shoe

Slide 26

Slide 26 text

Android Debugger : 201. Running on Main threads @hi_man_shoe

Slide 27

Slide 27 text

Android Debugger : 201.

Slide 28

Slide 28 text

Android Debugger : 201. @hi_man_shoe

Slide 29

Slide 29 text

Profiler : 202. - To improve performance issues on your app. - Helps us identify the issues. - Can help in CPU, memory, graphics, network, or the device battery. - Is natively available in Android Studio out of box! @hi_man_shoe

Slide 30

Slide 30 text

Profiler : 202. View > Tool Window > Pro fi ler @hi_man_shoe

Slide 31

Slide 31 text

Profiler : 202. The package @hi_man_shoe

Slide 32

Slide 32 text

Profiler : 202. @hi_man_shoe

Slide 33

Slide 33 text

Profiler : 202. CPU Usage of app in your device @hi_man_shoe

Slide 34

Slide 34 text

Profiler : 202. Memory used by the app @hi_man_shoe

Slide 35

Slide 35 text

Profiler : 202. @hi_man_shoe

Slide 36

Slide 36 text

Profiler : 202. @hi_man_shoe

Slide 37

Slide 37 text

Profiler : 202. Stats at any moment

Slide 38

Slide 38 text

Profiler : 202. @hi_man_shoe

Slide 39

Slide 39 text

Profiler : 202.

Slide 40

Slide 40 text

Profiler : 202. @hi_man_shoe

Slide 41

Slide 41 text

Going back to Memory Profiler @hi_man_shoe

Slide 42

Slide 42 text

Profiler : 202. @hi_man_shoe

Slide 43

Slide 43 text

Profiler : 202. @hi_man_shoe

Slide 44

Slide 44 text

Profiler : 202. Java @hi_man_shoe

Slide 45

Slide 45 text

Profiler : 202. Native @hi_man_shoe

Slide 46

Slide 46 text

Profiler : 202. Graphics and so on! @hi_man_shoe

Slide 47

Slide 47 text

Profiler : 202. Lets see Heap Dump? @hi_man_shoe

Slide 48

Slide 48 text

Profiler : 202. Heap dump recording

Slide 49

Slide 49 text

Profiler : 202. Classes in the code. @hi_man_shoe

Slide 50

Slide 50 text

App Inspection : 301. View > Tool Window > App Inspection @hi_man_shoe

Slide 51

Slide 51 text

App Inspection : 301. Lets you inspect Databases/Datastore @hi_man_shoe

Slide 52

Slide 52 text

App Inspection : 301. Inspect API calls :D @hi_man_shoe

Slide 53

Slide 53 text

App Inspection : 301. Inspect Workers! @hi_man_shoe

Slide 54

Slide 54 text

Database Inspection : 401. src: https://developer.android.com @hi_man_shoe

Slide 55

Slide 55 text

src: https://developer.android.com Write queries to test your DAO! Database Inspection : 401. @hi_man_shoe

Slide 56

Slide 56 text

Network Inspection : 402. @hi_man_shoe

Slide 57

Slide 57 text

Network Inspection : 402. Rules to manipulate response

Slide 58

Slide 58 text

Background Tasks: 403. Inspect Workers! @hi_man_shoe

Slide 59

Slide 59 text

UI Debugging : Compose. @hi_man_shoe

Slide 60

Slide 60 text

Problem? @hi_man_shoe

Slide 61

Slide 61 text

Problem? Rendering Performance Janks UI performance @hi_man_shoe

Slide 62

Slide 62 text

I/Choreographer: Skipped 115 frames! The application may be doing too much work on its main thread. @hi_man_shoe

Slide 63

Slide 63 text

UI Debugging : 501. - Help us build performant UI - Let us understanding places to improve/fix - Build global UI for 1000s of Phone and share best user experience. @hi_man_shoe

Slide 64

Slide 64 text

Layout inspector Layout inspector: 502 @hi_man_shoe

Slide 65

Slide 65 text

Layout inspector: 502 - Helps debug Layout - Gives count for Recomposition/Skips in Composable @hi_man_shoe

Slide 66

Slide 66 text

Layout inspector: 502 @hi_man_shoe

Slide 67

Slide 67 text

Layout inspector: 502 Recomposition count

Slide 68

Slide 68 text

Layout inspector: 502 Recomposition Skip count

Slide 69

Slide 69 text

Layout inspector: 502

Slide 70

Slide 70 text

Profiling HWUI : 503. Settings > Developer Option > Monitoring > Pro fi le HWUI rendering. @hi_man_shoe

Slide 71

Slide 71 text

Profiling HWUI : 503. - Each Screen has its own bar graph representing the UI changes. - vertical bar is a individual frame. - And height of it shows the time (ms) it took to render. @hi_man_shoe

Slide 72

Slide 72 text

Profiling HWUI : 503. Consider it threshold (16.67 ms) @hi_man_shoe

Slide 73

Slide 73 text

GPU Overdraw : 504. - The drawn pixels are not visible in the view displayed to the user - Can reduce performance. - More battery usage. - Bad user experience. @hi_man_shoe

Slide 74

Slide 74 text

GPU Overdraw : 504. src: https://developer.android.com/topic/performance/rendering/inspect-gpu-rendering

Slide 75

Slide 75 text

GPU Overdraw : 504. Settings > Developer Option > Hardware accelerated rendering > Debug GPU Overdraw. @hi_man_shoe

Slide 76

Slide 76 text

Fixing GPU Overdraw : 504. - Reduce nested layouts - Use inline Composables like Rows and Columns - Optimizing backgrounds and backgroundColor - Less recompositions in Composable and persisting state values in scope of composable. @hi_man_shoe

Slide 77

Slide 77 text

Strict Mode : 505. A developer too which detects things you might Be doing by accident and bring them to your attention so we can fi x. “ “ @hi_man_shoe

Slide 78

Slide 78 text

Strict Mode : 505. override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build() ) } } @hi_man_shoe

Slide 79

Slide 79 text

Strict Mode : 505. override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build() ) } } @hi_man_shoe

Slide 80

Slide 80 text

Strict Mode : 505. override fun onCreate() { super.onCreate() if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectAll() .penaltyLog() .build() ) } } @hi_man_shoe

Slide 81

Slide 81 text

Compose Compiler Report : 506. The compose compiler report generates report to determine which of you composable are skippable and which are not! @hi_man_shoe

Slide 82

Slide 82 text

Compose Compiler Report : 506. subprojects { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).con fi gureEach { kotlinOptions { if (project. fi ndProperty("composeCompilerReports") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } if (project. fi ndProperty("composeCompilerMetrics") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } } } }

Slide 83

Slide 83 text

Compose Compiler Report : 506. subprojects { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).con fi gureEach { kotlinOptions { if (project. fi ndProperty("composeCompilerReports") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } if (project. fi ndProperty("composeCompilerMetrics") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } } } }

Slide 84

Slide 84 text

Compose Compiler Report : 506. subprojects { tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).con fi gureEach { kotlinOptions { if (project. fi ndProperty("composeCompilerReports") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } if (project. fi ndProperty("composeCompilerMetrics") == "true") { freeCompilerArgs += [ "-P", "plugin:androidx.compose.compiler.plugins.kotlin:metricsDestination=" + project.buildDir.absolutePath + "/compose_compiler" ] } } } }

Slide 85

Slide 85 text

Compose Compiler Report : 506. ./gradlew assembleRelease -PcomposeCompilerReports=true @hi_man_shoe

Slide 86

Slide 86 text

• module-class.txt : A report on the stability of classes in this • module-composables.txt : A report on how restartable and skippable the composables are. • module-composables.csv : A CSV Version of report. Compose Compiler Report : 506. @hi_man_shoe

Slide 87

Slide 87 text

composables.txt restartable scheme("[androidx.compose.ui.UiComposable]") fun ServerList( stable index: Int unstable servers: List stable OnServerClick: Function1 stable modi fi er: Modi fi er? = @static Companion ) @hi_man_shoe

Slide 88

Slide 88 text

composables.txt restartable scheme("[androidx.compose.ui.UiComposable]") fun ServerList( stable index: Int unstable servers: List stable OnServerClick: Function1 stable modi fi er: Modi fi er? = @static Companion ) @hi_man_shoe

Slide 89

Slide 89 text

Fix. @Immutable data class ServerCollection( val servers: List = emptyList(), ) @hi_man_shoe

Slide 90

Slide 90 text

Or. @Immutable data class ComposeCollection(val data: List) @hi_man_shoe

Slide 91

Slide 91 text

Pull Request Run the Compiler check Comment in PR Compose Compiler Report : 506. @hi_man_shoe

Slide 92

Slide 92 text

Memory Leaks : 506. Cannot release the unused memory allocation from memory! “ “ @hi_man_shoe

Slide 93

Slide 93 text

- Wrong Usage of Threads. - Context :D - Patterns like Singleton. - Deregistering callbacks? Memory Leaks : 506. @hi_man_shoe

Slide 94

Slide 94 text

- Check for OutOfMemoryError :D - Start using LeakCanary (https://square.github.io/leakcanary/getting_started/) Memory Leaks : 506. @hi_man_shoe

Slide 95

Slide 95 text

Thank you. @hi_man_shoe