> For the complete documentation index, see [llms.txt](https://docs.luciq.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.luciq.ai/android/set-up-luciq-for-android/integrate-luciq-on-android/preserving-screen-names.md).

# Preserving Screen Names

Keep your original Activity and Fragment screen names readable on the Luciq dashboard when your Android app is built with a class-renaming obfuscator.

If your dashboard shows screen names like `zqx.a` or `b.c.d` instead of `CheckoutActivity` or `ProfileFragment`, your build is renaming those classes before they ship. Luciq identifies a screen by its runtime class name, so once the class is renamed, every product that reports a screen name reports the renamed one.

Luciq's Gradle plugin can bake the original class name into each Activity and Fragment at build time, so the readable name survives obfuscation. You turn it on with a single flag:

{% tabs %}
{% tab title="Gradle" %}
{% code overflow="wrap" %}

```gradle
luciq {
    keepScreenNames = true
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

### Why Your Screen Names Look Obfuscated

A screen's identity in the SDK is its runtime class name, and what happens to that name depends on which tool minifies your app.

* **AGP with plain R8.** Activities survive, because AGP generates keep rules for them from your `AndroidManifest.xml`. Fragments are not referenced in the manifest, so plain R8 renames them in every minified app.
* **Commercial obfuscators such as DexGuard or Appdome.** These replace R8, rewrite the manifest to match the new names, and can therefore rename Activities as well as Fragments.

On top of being unreadable, obfuscated names are unstable: obfuscators re-randomise them on every release, so the same screen produces a different name in each build and your metric groups fragment release after release.

{% hint style="warning" %}

#### Uploading Mapping Files Does Not Fix Screen Names

ProGuard/R8 mapping files deobfuscate crash **stack traces**. Screen names are captured at runtime and sent as data, so they never pass through the mapping file and are never deobfuscated by it. Uploading a mapping file is still required for readable stack traces — see [Deobfuscation for Android](/android/set-up-luciq-for-android/set-up-crash-reporting/deobfuscation-for-android.md) — but it is a separate concern from the names described on this page.
{% endhint %}

### Enabling keepScreenNames

{% hint style="info" %}
`keepScreenNames` is available starting from SDK version **19.13.0**. It is `false` by default, so apps that do not set it keep their current behavior.
{% endhint %}

**Step 1: Add the Plugin to your buildscript**

This is the same plugin artifact already used for mapping file upload and Fragment spans. If it is already in your buildscript, skip this step.

{% tabs %}
{% tab title="Gradle" %}
{% code overflow="wrap" %}

```gradle
buildscript {
    dependencies {
        classpath "ai.luciq.library:luciq-plugin:x.y.z"
    }
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

**Step 2: Apply the plugin in your app module**

Add `apply plugin: 'luciq'` to your app's Gradle file.

{% hint style="warning" %}

#### `keepScreenNames` Only Works Under the `luciq` Plugin ID

The other Luciq plugin IDs — `luciq-apm`, `luciq-crash` and `luciq-compiler-extension` — create the same shared `luciq { }` extension, so they **accept** `keepScreenNames` without failing the build, but they do not register the bytecode transform that acts on it.

If you already apply one of those plugin IDs for another reason, apply `luciq` as well. When the flag is set without the `luciq` plugin ID applied, the build prints a warning at configuration time rather than silently doing nothing.
{% endhint %}

**Step 3: Configure the plugin**

{% tabs %}
{% tab title="Gradle" %}
{% code overflow="wrap" %}

```gradle
luciq {
    /**
     * Preserves the original Activity and Fragment class names used as screen
     * names across Luciq products, even when the classes are renamed by an
     * obfuscator.
     * Required: No
     * Default: false
     */
    keepScreenNames = true
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

Build a release variant with your obfuscator in place, and the screens reported by the SDK carry their original names.

{% hint style="success" %}

#### Do Not Add a Keep Rule for Your Screens

You do not need — and should not add — a ProGuard/R8 keep rule for your Activities or Fragments. Keeping those classes unrenamed would readably expose exactly the classes you are paying an obfuscator to protect, which defeats the purpose. `keepScreenNames` gives you readable names on the dashboard while your classes stay obfuscated in the shipped app.
{% endhint %}

### What It Affects

With `keepScreenNames` enabled, readable screen names appear across every Luciq product that reports a screen:

* **APM**: UI traces, Screen Loading, App Launch and Fragment spans.
* **Crash Reporting and ANRs**: the current view / Activity name shown on the report.
* **Repro Steps** and user steps: the screen name on each step, including taps, swipes and scrolls.
* **Session Replay**: the screen names shown in the replay timeline.
* **Bug Reporting**: the reported current view.

### How It Works

Before R8 or your obfuscator runs, the Gradle plugin's ASM transform gives every Activity and Fragment subclass a marker interface and a generated method whose entire body returns the original fully qualified class name as a string literal. Obfuscators rename symbols, but they never rewrite string literals, so the baked-in name survives renaming and the SDK reads it at runtime instead of the renamed class name.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.luciq.ai/android/set-up-luciq-for-android/integrate-luciq-on-android/preserving-screen-names.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
