Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 2.2.13

### Added
- Added the isAsyncConfigFetchEnabled API to enable/disable async config fetch optimization.

### Fixed
- Fixed memory leaks in session recording service that could retain destroyed activities and services.

## 2.2.12

### Fixed
Expand Down
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ DevRev SDK, used for integrating DevRev services into your Android app.
- [Dynamic theme configuration](#dynamic-theme-configuration)
- [Analytics](#analytics)
- [Session analytics](#session-analytics)
- [Opt in or out](#opt-in-or-out)
- [Opt in or out](#opt-in-or-out)
- [Session recording](#session-recording)
- [Async config fetch](#async-config-fetch)
- [Session properties](#session-properties)
- [Mask sensitive data](#mask-sensitive-data)
- [Mask using predefined tags](#mask-using-predefined-tags)
Expand Down Expand Up @@ -589,7 +590,7 @@ For example:

The DevRev SDK provides observability features to help you understand how your users are interacting with your app.

### Opt in or out
#### Opt in or out

Session analytics features are opted-in by default, enabling them from the start. However, you can opt-out using the following method:

Expand Down Expand Up @@ -675,6 +676,36 @@ To check if on-demand sessions are enabled, use:
```java
DevRevObservabilityExtKt.areOnDemandSessionsEnabled(DevRev.INSTANCE);
```

#### Async config fetch

> [!NOTE]
> The sessions will only be uploaded when the app is in the background.

The SDK can be configured to fetch configuration asynchronously to improve app startup time. When enabled, the SDK uses cached configuration for immediate startup and fetches fresh configuration from the server in the background.

> [!NOTE]
> This setting should be called before `startRecording()` for it to take effect. Default is disabled for backward compatibility.

- Kotlin
```kotlin
DevRev.setAsyncConfigFetchEnabled(context, true)
```
- Java
```java
DevRevObservabilityExtKt.setAsyncConfigFetchEnabled(DevRev.INSTANCE, context, true);
```

**Behavior when enabled:**
- Uses cached config immediately to decide whether to start recording
- If cached config says recording is disabled, recording won't start (respects dashboard setting)
- Fetches fresh config in background without blocking startup
- If fresh config disables recording after it started, recording stops immediately
- Session uploads are deferred to when the app is in the background
- Crash and ANR reports are prioritized and uploaded immediately
- Regular session uploads occur sequentially (one at a time) to reduce network contention

This optimization is particularly beneficial for apps experiencing slow startup times on poor network connections.

#### Session properties

Expand Down
15 changes: 15 additions & 0 deletions docs/html/core/ai.devrev.sdk/-dev-rev/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,21 @@ <h2 class="tableheader">Functions</h2>
</div>
</div>
</div>
<a data-name="931310931%2FFunctions%2F-2055549142" anchor-label="setAsyncConfigFetchEnabled" id="931310931%2FFunctions%2F-2055549142" data-filterable-set=":core/main"></a>
<div class="table-row table-row_content" data-togglable="EXTENSION_FUNCTION" data-filterable-current=":core/main" data-filterable-set=":core/main">
<div class="main-subrow keyValue ">
<div class=""><span class="inline-flex">
<div><a href="../set-async-config-fetch-enabled.html"><span>set</span><wbr></wbr><span>Async</span><wbr></wbr><span>Config</span><wbr></wbr><span>Fetch</span><wbr></wbr><span><span>Enabled</span></span></a></div>
<span class="anchor-wrapper"><span class="anchor-icon" pointing-to="931310931%2FFunctions%2F-2055549142"></span>
<div class="copy-popup-wrapper "><span class="copy-popup-icon"></span><span>Link copied to clipboard</span></div>
</span></span></div>
<div>
<div class="title">
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="index.html">DevRev</a><span class="token punctuation">.</span><a href="../set-async-config-fetch-enabled.html"><span class="token function">setAsyncConfigFetchEnabled</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter ">context<span class="token operator">: </span><a href="https://developer.android.com/reference/kotlin/android/content/Context.html">Context</a><span class="token punctuation">, </span></span><span class="parameter ">enabled<span class="token operator">: </span><a href="https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html">Boolean</a></span></span><span class="token punctuation">)</span></div><div class="brief "><p class="paragraph">Enables or disables async config fetch optimization to improve app startup time.</p></div></div></div>
</div>
</div>
</div>
</div>
<a data-name="517623941%2FFunctions%2F-2055549142" anchor-label="setCustomKey" id="517623941%2FFunctions%2F-2055549142" data-filterable-set=":core/main"></a>
<div class="table-row table-row_content" data-filterable-current=":core/main" data-filterable-set=":core/main">
<div class="main-subrow keyValue ">
Expand Down
15 changes: 15 additions & 0 deletions docs/html/core/ai.devrev.sdk/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,21 @@ <h2 class="tableheader">Functions</h2>
</div>
</div>
</div>
<a data-name="931310931%2FFunctions%2F-2055549142" anchor-label="setAsyncConfigFetchEnabled" id="931310931%2FFunctions%2F-2055549142" data-filterable-set=":core/main"></a>
<div class="table-row table-row_content" data-filterable-current=":core/main" data-filterable-set=":core/main">
<div class="main-subrow keyValue ">
<div class=""><span class="inline-flex">
<div><a href="set-async-config-fetch-enabled.html"><span>set</span><wbr></wbr><span>Async</span><wbr></wbr><span>Config</span><wbr></wbr><span>Fetch</span><wbr></wbr><span><span>Enabled</span></span></a></div>
<span class="anchor-wrapper"><span class="anchor-icon" pointing-to="931310931%2FFunctions%2F-2055549142"></span>
<div class="copy-popup-wrapper "><span class="copy-popup-icon"></span><span>Link copied to clipboard</span></div>
</span></span></div>
<div>
<div class="title">
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="-dev-rev/index.html">DevRev</a><span class="token punctuation">.</span><a href="set-async-config-fetch-enabled.html"><span class="token function">setAsyncConfigFetchEnabled</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter ">context<span class="token operator">: </span><a href="https://developer.android.com/reference/kotlin/android/content/Context.html">Context</a><span class="token punctuation">, </span></span><span class="parameter ">enabled<span class="token operator">: </span><a href="https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html">Boolean</a></span></span><span class="token punctuation">)</span></div><div class="brief "><p class="paragraph">Enables or disables async config fetch optimization to improve app startup time.</p></div></div></div>
</div>
</div>
</div>
</div>
<a data-name="-487263811%2FFunctions%2F-2055549142" anchor-label="setDeviceLocation" id="-487263811%2FFunctions%2F-2055549142" data-filterable-set=":core/main"></a>
<div class="table-row table-row_content" data-filterable-current=":core/main" data-filterable-set=":core/main">
<div class="main-subrow keyValue ">
Expand Down
132 changes: 132 additions & 0 deletions docs/html/core/ai.devrev.sdk/set-async-config-fetch-enabled.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html class="no-js" lang="en">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1" charset="UTF-8">
<title>setAsyncConfigFetchEnabled</title>
<link href="../../images/logo-icon.svg" rel="icon" type="image/svg">
<script>var pathToRoot = "../../";</script>
<script>document.documentElement.classList.replace("no-js", "js");</script>
<script>const storage = localStorage.getItem("dokka-dark-mode")
if (storage == null) {
const osDarkSchemePreferred = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
if (osDarkSchemePreferred === true) {
document.getElementsByTagName("html")[0].classList.add("theme-dark")
}
} else {
const savedDarkMode = JSON.parse(storage)
if (savedDarkMode === true) {
document.getElementsByTagName("html")[0].classList.add("theme-dark")
}
}
</script>
<script type="text/javascript" src="https://unpkg.com/kotlin-playground@1/dist/playground.min.js" async="async"></script>
<script type="text/javascript" src="../../scripts/sourceset_dependencies.js" async="async"></script>
<link href="../../styles/style.css" rel="Stylesheet">
<link href="../../styles/main.css" rel="Stylesheet">
<link href="../../styles/prism.css" rel="Stylesheet">
<link href="../../styles/logo-styles.css" rel="Stylesheet">
<link href="../../ui-kit/ui-kit.min.css" rel="Stylesheet">
<script type="text/javascript" src="../../scripts/safe-local-storage_blocking.js"></script>
<script type="text/javascript" src="../../scripts/navigation-loader.js" async="async"></script>
<script type="text/javascript" src="../../scripts/platform-content-handler.js" async="async"></script>
<script type="text/javascript" src="../../scripts/main.js" defer="defer"></script>
<script type="text/javascript" src="../../scripts/prism.js" async="async"></script>
<script type="text/javascript" src="../../ui-kit/ui-kit.min.js" defer="defer"></script>
</head>
<body>
<div class="root">
<header class="navigation theme-dark" id="navigation-wrapper" role="banner">
<a class="library-name--link" href="../../index.html" tabindex="1">
core
</a>
<button class="navigation-controls--btn navigation-controls--btn_toc ui-kit_mobile-only" id="toc-toggle"
type="button">Toggle table of contents
</button>
<div class="navigation-controls--break ui-kit_mobile-only"></div>
<div class="library-version" id="library-version">
</div>
<div class="navigation-controls">
<ul class="filter-section filter-section_loading" id="filter-section" aria-label="Target filter">
<button class="platform-tag platform-selector jvm-like" data-active="" aria-pressed="true"
data-filter=":core/main">androidJvm</button>
<div class="dropdown filter-section--dropdown" data-role="dropdown" id="filter-section-dropdown">
<button class="button button_dropdown filter-section--dropdown-toggle" role="combobox"
data-role="dropdown-toggle"
aria-controls="platform-tags-listbox"
aria-haspopup="listbox"
aria-expanded="false"
aria-label="Toggle source sets"
></button>
<ul role="listbox" id="platform-tags-listbox" class="dropdown--list" data-role="dropdown-listbox" aria-label="Target filter">
<div class="dropdown--header"><span>Target filter</span>
<button class="button" data-role="dropdown-toggle" aria-label="Close target filter">
<i class="ui-kit-icon ui-kit-icon_cross"></i>
</button>
</div>
<li role="option" class="dropdown--option platform-selector-option jvm-like" tabindex="0">
<label class="checkbox">
<input type="checkbox" class="checkbox--input" id=":core/main"
data-filter=":core/main"/>
<span class="checkbox--icon"></span>
androidJvm
</label>
</li>
</ul>
<div class="dropdown--overlay"></div>
</div>
</ul>
<button class="navigation-controls--btn navigation-controls--btn_theme" id="theme-toggle-button"
type="button">Switch theme
</button>
<div class="navigation-controls--btn navigation-controls--btn_search" id="searchBar" role="button">Search in
API
</div>
</div>
</header>
<div id="container">
<nav id="leftColumn" class="sidebar" data-item-type="SECTION" data-item-config='{"defaultSize": 280, "minSize": 200, "maxSize": 400}'>
<a class="toc--skip-link" href="#main">Skip to content</a>
<div class="dropdown theme-dark_mobile" data-role="dropdown" id="toc-dropdown">
<ul role="listbox" id="toc-listbox" class="dropdown--list dropdown--list_toc-list"
data-role="dropdown-listbox" aria-label="Table of contents">
<div class="dropdown--header">
<span>
core
</span>
<button class="button" data-role="dropdown-toggle" aria-label="Close table of contents">
<i class="ui-kit-icon ui-kit-icon_cross"></i>
</button>
</div>
<div class="sidebar--inner" id="sideMenu"></div>
</ul>
<div class="dropdown--overlay"></div>
</div>
</nav>
<div id="resizer" class="resizer" data-item-type="BAR"></div>
<div id="main" data-item-type="SECTION" role="main">
<div class="main-content" data-page-type="member" id="content" pageIds="core::ai.devrev.sdk//setAsyncConfigFetchEnabled/ai.devrev.sdk.DevRev#android.content.Context#kotlin.Boolean/PointingToDeclaration//-2055549142">
<div class="breadcrumbs"><a href="../../index.html">core</a><span class="delimiter">/</span><a href="index.html">ai.devrev.sdk</a><span class="delimiter">/</span><span class="current">setAsyncConfigFetchEnabled</span></div>
<div class="cover ">
<h1 class="cover"><span>set</span><wbr></wbr><span>Async</span><wbr></wbr><span>Config</span><wbr></wbr><span>Fetch</span><wbr></wbr><span><span>Enabled</span></span></h1>
</div>
<div class="platform-hinted " data-platform-hinted="data-platform-hinted"><div class="content sourceset-dependent-content" data-active="" data-togglable=":core/main"><div class="symbol monospace"><span class="token keyword">fun </span><a href="-dev-rev/index.html">DevRev</a><span class="token punctuation">.</span><a href="set-async-config-fetch-enabled.html"><span class="token function">setAsyncConfigFetchEnabled</span></a><span class="token punctuation">(</span><span class="parameters "><span class="parameter ">context<span class="token operator">: </span><a href="https://developer.android.com/reference/kotlin/android/content/Context.html">Context</a><span class="token punctuation">, </span></span><span class="parameter ">enabled<span class="token operator">: </span><a href="https://kotlinlang.org/api/core/kotlin-stdlib/kotlin/-boolean/index.html">Boolean</a></span></span><span class="token punctuation">)</span></div><p class="paragraph">Enables or disables async config fetch optimization to improve app startup time.</p><p class="paragraph">When enabled, the SDK uses cached configuration for immediate startup and fetches fresh configuration from the server in the background. This significantly improves app startup time on slow networks.</p><p class="paragraph"><strong>Behavior when enabled:</strong></p><ul><li><p class="paragraph">Uses cached config immediately to decide whether to start recording</p></li><li><p class="paragraph">If cached config says recording disabled, recording won't start (respects dashboard setting)</p></li><li><p class="paragraph">Fetches fresh config in background without blocking startup</p></li><li><p class="paragraph">If fresh config disables recording after it started, recording stops immediately</p></li></ul><p class="paragraph"><strong>Important:</strong> This should be called before <a href="start-recording.html">startRecording</a> for the setting to take effect. Default is disabled (false) for backward compatibility.</p><h4 class="tableheader">Parameters</h4><div class="table"><div class="table-row table-row_content" data-filterable-current=":core/main" data-filterable-set=":core/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>context</span></span></u></div></span></div><div><div class="title"><p class="paragraph">An application context</p></div></div></div></div><div class="table-row table-row_content" data-filterable-current=":core/main" data-filterable-set=":core/main"><div class="main-subrow keyValue "><div class=""><span class="inline-flex"><div><u><span><span>enabled</span></span></u></div></span></div><div><div class="title"><p class="paragraph">true to enable async config fetch, false to use blocking fetch (default)</p></div></div></div></div></div></div></div>
</div>
<div class="footer">
<div class="footer--container">
<a href="#content" id="go-to-top-link" class="footer--button footer--button_go-to-top"></a>
<div class="footer--content">
<div>
<span>Generated by </span>
<a class="footer--link footer--link_external" href="https://github.com/Kotlin/dokka">
Dokka
</a>
<div>© 2026 Copyright</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
1 change: 1 addition & 0 deletions docs/html/core/package-list
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ $dokka.location:ai.devrev.sdk//resumeRecording/ai.devrev.sdk.DevRev#/PointingToD
$dokka.location:ai.devrev.sdk//resumeUserInteractionTracking/ai.devrev.sdk.DevRev#/PointingToDeclaration/core/ai.devrev.sdk/resume-user-interaction-tracking.html
$dokka.location:ai.devrev.sdk//sendException/ai.devrev.sdk.DevRev#kotlin.Throwable#kotlin.String/PointingToDeclaration/core/ai.devrev.sdk/send-exception.html
$dokka.location:ai.devrev.sdk//setAppFrameworkInfo/ai.devrev.sdk.DevRev#android.content.Context#kotlin.String#kotlin.String/PointingToDeclaration/core/ai.devrev.sdk/set-app-framework-info.html
$dokka.location:ai.devrev.sdk//setAsyncConfigFetchEnabled/ai.devrev.sdk.DevRev#android.content.Context#kotlin.Boolean/PointingToDeclaration/core/ai.devrev.sdk/set-async-config-fetch-enabled.html
$dokka.location:ai.devrev.sdk//setDeviceLocation/ai.devrev.sdk.DevRev#kotlin.Double#kotlin.Double/PointingToDeclaration/core/ai.devrev.sdk/set-device-location.html
$dokka.location:ai.devrev.sdk//setInScreenTransitioning/ai.devrev.sdk.DevRev#kotlin.Boolean/PointingToDeclaration/core/ai.devrev.sdk/set-in-screen-transitioning.html
$dokka.location:ai.devrev.sdk//setMaskLocationProvider/ai.devrev.sdk.DevRev#com.userexperior.bridge.model.MaskLocationProvider/PointingToDeclaration/core/ai.devrev.sdk/set-mask-location-provider.html
Expand Down
Loading