Demeter is a performance measurement library that could simplify performance issues investigation in your app. It's also useful to give a special prepared build with Demeter inside to your QA team to use it while regress process and upload performace report in the end.
- Tracer: Measures project methods with information about an execution thread, a consuming time and helps to sort by hazard level
- Inject: Wraps and calculates Injected constructors and its dependencies. It's useful to dig up problems with a dagger graph
- Enriches methods with profileable sections that helps to investigate problems in an Android Profiler or Perfetto
- Compose: observe StateObject changes and discover it
- Exports measurements to the excel format and Flipper
Injected constuctor
Tracer for methods
Method export
Inspect Compose recompositions and ObjectStates
Integrated Demeter represents an Activity that starts by notification click in any place of your application.
Demeter foundation consists of libraries:
demeter-core
- contains base interface without implementations. It also could be applied for release build typedemeter-profiler
- the main profiler implementation that should be applied for dev build type. You must check this artifact is not attached to release build type!-
base
- base profiler logic
-
ui
- profiler ui
demeter-gradle-plugin
- main Demeter Gradle Plugin
Functionality is provided via specifying profiler plugins by consumer needs:
demeter-tracer-profiler-plugin
- tracing methodsdemeter-inject-profiler-plugin
- analyzing @Inject constructor initializationdemeter-compose-profiler-plugin
- Jetpack Compose analyzer
For dev build type:
- Add demeter plugin
plugins {
id("com.yandex.demeter")
}
- Add implementation of the profiler:
dependencies {
// if buildType == Dev/Debug/etc...
implementation("com.yandex.demeter:profiler")
}
- Open your AndroidManifest and add:
<profileable
android:enabled="true"
android:shell="true"
tools:ignore="UnusedAttribute" />
That helps Demeter to check and profile methods better. Do it only for Dev build types!
- Add in your Application class:
override fun onCreate() {
super.onCreate()
...
Demeter.init(
DemeterInitializer(
context = this,
flipperEnabled = false, // true - turn on flipper notifications
profilerEnabled = false, // true - turn on trace section for profiler
)
)
...
}
- Configure demeter plugin. You can apply only subplugins you need:
demeter {
tracer {
includedClasses = listOf("com.yandex.myapp") // list of packages that should be analyzed
}
inject {
includedClasses = listOf("com.yandex.myapp") // list of packages that should be analyzed
excludedClasses = listOf("com.yandex.myapp.excluded") // list of packages that shouldn't be analyzed
}
compose() // turn on compose inspections
}
- Run and control!
Demeter feature plugins can be applied via main plugin:
plugins {
id("com.yandex.demeter")
}
or directly:
plugins {
id("com.yandex.demeter.tracer")
id("com.yandex.demeter.inject")
...
}
Main plugin applies only plugins you specified in demeter
block
Feature plugins:
demeter-tracer-gradle-plugin
demeter-inject-gradle-plugin
demeter-compose-gradle-plugin
Problem: I get crash with stacktrace like
java.lang.AssertionError: Built-in class kotlin.Any is not found
Solution: Check you don't exclude .kotlin_builtins
files from build
packagingOptions {
resources {
excludes += ['**/kotlin/**', '**.kotlin_builtins'] // or any other .kotlin_builtins exclude options
}
}