Android ListView点击跳转异常:Firebase数据加载后无响应
Got it, let's break down this issue you're facing—it's super common when mixing Firebase, Android ListViews, and release build obfuscation! Let's jump straight to the root cause and fixes:
Root Cause Analysis
Here's exactly what's happening:
- In debug builds (your dev phase), code obfuscation (R8) is disabled. Your Workout data model class uses the original field names (like
type) that match exactly with the old data stored in Firebase. So when you click a list item, the app correctly reads theCardio/Othervalue and triggers the right intent. - When you package a release build, R8 automatically renames class fields, methods, and even class names to shrink the app size. This means your model's
typefield gets renamed (e.g., toa). Old Firebase data still uses the originaltypekey, so the app can't map it to the obfuscated field—resulting in anulltype value. Your click logic doesn't trigger any action because it can't find a matching type. - New workouts saved from the release build use the obfuscated field name (e.g.,
a) when writing to Firebase, so the app can parse the type correctly and jump as expected.
Exact Fixes to Implement
1. Protect Your Data Model from Obfuscation
You need to tell R8 to leave your Workout model class (and its critical fields) untouched. There are two easy ways to do this:
Option A: Use @Keep Annotations
Add the @Keep annotation to your model class, its no-arg constructor (required for Firebase serialization), and the type field/getter:
import androidx.annotation.Keep; @Keep // Preserves the entire class public class Workout { @Keep // Preserves this field name private String name; @Keep // Preserves the type field so Firebase can map old data private String type; // Firebase requires an empty constructor—keep it too! @Keep public Workout() {} // Keep getters so the app can access the type value @Keep public String getType() { return type; } // Add other constructors/setters as needed, mark with @Keep if necessary }
Option B: Add ProGuard Rules
If you prefer not to use annotations, add these lines to your proguard-rules.pro file (replace the class path with your actual model's package):
# Preserve the Workout model class and all its fields/methods -keep class com.your.app.package.models.Workout { *; }
2. Add Null Safety to Your Click Logic
Even after fixing obfuscation, adding a safety check prevents silent failures if any data has missing type values. Update your ListView item click listener:
listView.setOnItemClickListener((parent, view, position, id) -> { Workout selectedWorkout = workoutList.get(position); String workoutType = selectedWorkout.getType(); // Handle null or missing type values if (workoutType == null) { Toast.makeText(this, "Could not recognize workout type", Toast.LENGTH_SHORT).show(); return; } Intent targetIntent; switch (workoutType) { case "Cardio": targetIntent = new Intent(this, CardioActivity.class); break; case "Other": targetIntent = new Intent(this, OtherActivity.class); break; default: Toast.makeText(this, "Unknown workout type", Toast.LENGTH_SHORT).show(); return; } startActivity(targetIntent); });
3. (Optional) Normalize Type Matching
If your old Firebase data has inconsistent capitalization (e.g., "cardio" instead of "Cardio"), normalize the string before checking:
switch (workoutType.trim().toLowerCase()) { case "cardio": // Jump to CardioActivity break; // ... rest of the cases }
内容的提问来源于stack exchange,提问作者Mohan Adhikari

