Troubleshooting & FAQ
Common issues, solutions, and frequently asked questions for NetFUNNEL Android Agent integration.
Table of Contents
- Installation Issues
- Initialization Issues
- Function Call Errors
- Network & Connection Issues
- Waiting Room Issues
- Key Management Issues
- Configuration Issues
- Build & Environment Issues
- FAQ
Installation Issues
AAR File Not Loading
Symptoms:
- Build errors related to NetFUNNEL classes
- "Cannot resolve symbol" errors
- AAR file not found errors
Solutions:
- Check AAR file location: Ensure the
.aarfile is inapp/libs/directory - Verify build.gradle configuration: Check dependencies are correctly added
- Clean and rebuild: Clean project and rebuild
- Check file permissions: Ensure AAR file is readable
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
// Verify in build.gradle.kts
dependencies {
implementation(files("libs/netfunnel-android-agent-release-{{latest}}.aar"))
}
// Verify in build.gradle
dependencies {
implementation files('libs/netfunnel-android-agent-release-{{latest}}.aar')
}
External Dependencies Not Resolved
Symptoms:
- Ktor or Kotlinx Serialization not found
- Build errors for external libraries
- Missing dependency warnings
Solutions:
- Add required dependencies: Ensure all external dependencies are added
- Check versions: Use compatible versions
- Sync project: Sync project with Gradle files
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
// Add required dependencies
dependencies {
val ktorVersion = "2.3.12"
val serializationVersion = "1.6.3"
implementation("io.ktor:ktor-client-core:$ktorVersion")
implementation("io.ktor:ktor-client-okhttp:$ktorVersion")
implementation("io.ktor:ktor-client-content-negotiation:$ktorVersion")
implementation("io.ktor:ktor-serialization-gson:$ktorVersion")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
}
// Add required dependencies
dependencies {
def ktorVersion = "2.3.12"
def serializationVersion = "1.6.3"
implementation "io.ktor:ktor-client-core:$ktorVersion"
implementation "io.ktor:ktor-client-okhttp:$ktorVersion"
implementation "io.ktor:ktor-client-content-negotiation:$ktorVersion"
implementation "io.ktor:ktor-serialization-gson:$ktorVersion"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion"
}
Build Configuration Issues
Symptoms:
- Compilation errors
- Incompatible API level errors
- Java version compatibility issues
Solutions:
- Check API levels: Ensure
minSdk >= 22andtargetSdk >= 22 - Verify Java version: Use Java 1.8 or higher
- Check build features: Enable
viewBinding = true
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
// Verify build.gradle.kts configuration
android {
compileSdk = 34
defaultConfig {
minSdk = 22
targetSdk = 34
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
viewBinding = true
}
}
// Verify build.gradle configuration
android {
compileSdk 34
defaultConfig {
minSdk 22
targetSdk 34
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
Initialization Issues
Agent Not Initializing
Symptoms:
- No NetFUNNEL logs in Logcat
- Functions not available
- Bypass mode behavior
Solutions:
- Check initialization location: Ensure initialization is in
Application.onCreate() - Verify parameters: Check all required parameters are provided
- Check client ID: Ensure
clientIdis correct and accessible - Enable logging: Set
printLog = truefor debugging
- Kotlin
- Java
// Correct initialization
class SampleApplication : Application() {
override fun onCreate() {
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
printLog = true // Enable for debugging
)
super.onCreate()
}
}
// Correct initialization
public class SampleApplication extends Application {
@Override
public void onCreate() {
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
super.onCreate();
}
}
Manifest Registration Missing
Symptoms:
- Application class not being called
- Initialization not happening
- App crashes on startup
Solutions:
- Register Application class: Add to
AndroidManifest.xml - Check class name: Ensure correct class name is used
- Verify package: Check package name matches
<!-- AndroidManifest.xml -->
<application
android:name=".SampleApplication"
android:allowBackup="true">
<!-- Your activities -->
</application>
Bypass Mode (No Waiting Room)
Symptoms:
- Users access app directly without waiting room
- No NetFUNNEL traffic control
- Functions work but no protection
Solutions:
- Check client ID: Ensure
clientIdis correct and accessible - Verify segment status: Check segment is activated in console
- Check Limited Inflow: Verify Limited Inflow is not set to unlimited
- Enable logging: Check logs for initialization errors
Function Call Errors
"Netfunnel is not initialized" Error
Symptoms:
IllegalStateException: Netfunnel is not initialized- Functions throw exceptions
- App crashes when calling NetFUNNEL functions
Solutions:
- Check initialization: Ensure
Netfunnel.initialize()is called first - Check timing: Don't call functions before initialization
- Verify Application class: Ensure Application class is properly registered
- Kotlin
- Java
// Check if initialized before calling functions
if (Netfunnel.isInitialized()) {
Netfunnel.nfStart(projectKey, segmentKey, callback, this)
} else {
Log.e("NetFUNNEL", "Agent not initialized")
// Handle error or initialize
}
// Check if initialized before calling functions
if (Netfunnel.INSTANCE.isInitialized()) {
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, this);
} else {
Log.e("NetFUNNEL", "Agent not initialized");
// Handle error or initialize
}
Callback Not Executing
Symptoms:
nfStartcalled but callback never fires- No response received
- App hangs waiting for callback
Solutions:
- Check network: Verify network requests to NetFUNNEL server
- Enable logging: Set
printLog = truefor debugging - Check segment status: Ensure segment is not in Block state
- Verify callback implementation: Ensure callback is properly implemented
- Kotlin
- Java
// Enable logging for debugging
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
printLog = true // Enable logging
)
// Check logs in Logcat for NetFUNNEL messages
// Enable logging for debugging
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
// Check logs in Logcat for NetFUNNEL messages
Activity Context Issues
Symptoms:
IllegalArgumentException: Activity cannot be null- Context-related errors
- App crashes when calling functions
Solutions:
- Check activity context: Ensure valid Activity is passed
- Check timing: Don't call functions after Activity is destroyed
- Use proper lifecycle: Call functions in appropriate lifecycle methods
- Kotlin
- Java
// Correct usage
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Safe to call here
Netfunnel.nfStart(projectKey, segmentKey, callback, this)
}
// Avoid calling after onDestroy
override fun onDestroy() {
super.onDestroy()
// Don't call NetFUNNEL functions here
}
// Correct usage
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Safe to call here
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, this);
}
// Avoid calling after onDestroy
@Override
protected void onDestroy() {
super.onDestroy();
// Don't call NetFUNNEL functions here
}
Network & Connection Issues
Network Timeout Errors
Symptoms:
NetworkErrorwith status code 1002- Requests timing out
- Callbacks not received
Solutions:
- Increase timeout: Set
networkTimeoutto higher value (max 10000ms) - Retry configuration: Increase
retryCount - Network recovery: Enable
useNetworkRecoveryMode = true
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
networkTimeout = 5000, // Increase timeout
retryCount = 3, // Increase retries
errorBypass = false
)
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}",
5000, // Increase timeout
3, // Increase retries
false,
false
);
Network Not Connected Errors
Symptoms:
NetworkErrorwith status code 1001- No internet connectivity
- Network permission issues
Solutions:
- Check connectivity: Verify internet connection
- Check permissions: Ensure
INTERNETpermission is granted - Check firewall: Ensure NetFUNNEL domains are not blocked
- Implement error handling: Handle NetworkError appropriately
<!-- AndroidManifest.xml -->
<uses-permission android:name="android.permission.INTERNET" />
- Kotlin
- Java
// Handle network errors
private val callback = object : NetfunnelCallback() {
override fun onNetworkError(statusCode: Int, message: String) {
when (statusCode) {
1001 -> {
// Network not connected
showNetworkErrorDialog()
}
1002 -> {
// Network timeout
showTimeoutDialog()
}
}
}
}
// Handle network errors
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
switch (statusCode) {
case 1001:
// Network not connected
showNetworkErrorDialog();
break;
case 1002:
// Network timeout
showTimeoutDialog();
break;
}
}
};
Server Communication Issues
Symptoms:
- No response from NetFUNNEL server
- HTTP errors in logs
- Authentication failures
Solutions:
- Check client configuration: Verify clientId is correct
- Check authentication: Ensure valid clientId
- Check network: Verify network connectivity to NetFUNNEL servers
- Check logs: Enable logging to see detailed error messages
Waiting Room Issues
Waiting Room Not Displaying
Symptoms:
- No waiting room appears
- Users proceed directly
- No visual feedback
Solutions:
- Check Limited Inflow: Set to 0 for testing
- Check segment activation: Ensure segment is activated
- Check template settings: Verify
useNetfunnelTemplate = true - Check callback implementation: Ensure callbacks are properly implemented
- Kotlin
- Java
// Enable logging for debugging
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
printLog = true // Enable logging
)
// Enable logging for debugging
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
Waiting Room Stuck (Never Ends)
Symptoms:
- Waiting room appears but never allows entry
- Infinite waiting
- No progress indication
Solutions:
- Check Limited Inflow: Increase Limited Inflow value
- Check segment status: Ensure segment is not in Block state
- Check network: Verify network connectivity
- Check server status: Verify NetFUNNEL server status
Custom Template Issues
Symptoms:
- Custom waiting room not updating
onContinuecallback not called- UI not reflecting queue status
Solutions:
- Disable template: Set
useNetfunnelTemplate = false - Implement onContinue: Handle
onContinuecallback - Check callback implementation: Ensure proper callback setup
- Kotlin
- Java
// Basic configuration
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
errorBypass = false
)
// Implement onContinue callback
private val callback = object : NetfunnelCallback() {
override fun onContinue(statusCode: Int, message: String, aheadWait: Int, behindWait: Int, waitTime: String, progressRate: Int) {
// Update your custom waiting room UI
updateCustomWaitingRoom(aheadWait, behindWait, waitTime, progressRate)
}
}
// Basic configuration
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
// Implement onContinue callback
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onContinue(int statusCode, @NonNull String message, int aheadWait, int behindWait, @NonNull String waitTime, int progressRate) {
// Update your custom waiting room UI
updateCustomWaitingRoom(aheadWait, behindWait, waitTime, progressRate);
}
};
Key Management Issues
Key Not Returned
Symptoms:
- Next users remain waiting indefinitely
- Queue doesn't progress
- Server errors about key management
Solutions:
- Always call nfStop: Ensure
nfStop/nfStopSectionis called - Error handling: Return key even in error scenarios
- Check timing: Don't call stop before start completes
- Check key matching: Use identical keys for start/stop
- Kotlin
- Java
// Always return key
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
try {
performAction()
} finally {
// Always return key
Netfunnel.nfStop(projectKey, segmentKey, completeCallback)
}
}
override fun onError(statusCode: Int, message: String) {
// Return key even on error
Netfunnel.nfStop(projectKey, segmentKey, completeCallback)
}
}
// Always return key
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
try {
performAction();
} finally {
// Always return key
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback);
}
}
@Override
public void onError(int statusCode, @NonNull String message) {
// Return key even on error
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback);
}
};
Key Mismatch Errors
Symptoms:
- Server errors about invalid keys
- Key not found errors
- Function calls fail
Solutions:
- Key consistency: Use identical keys for start/stop functions
- Key scope: Don't reuse keys across different actions
- Timing: Don't call stop before start completes
- Check console: Verify keys match console exactly
- Kotlin
- Java
// Use consistent keys
val projectKey = "service_1"
val segmentKey = "segKey_123"
// Start
Netfunnel.nfStart(projectKey, segmentKey, callback, this)
// Stop (must use same keys)
Netfunnel.nfStop(projectKey, segmentKey, completeCallback)
// Use consistent keys
String projectKey = "service_1";
String segmentKey = "segKey_123";
// Start
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, this);
// Stop (must use same keys)
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback);
Configuration Issues
Wrong Project/Segment Keys
Symptoms:
- Functions called but no effect
- Wrong segment behavior
- Server errors
Solutions:
- Console verification: Double-check keys in NetFUNNEL console
- Copy exactly: Copy keys exactly as shown in console
- Environment: Ensure using correct environment (prod vs staging)
- Check segment type: Ensure using correct segment type (Basic vs Section)
Parameter Validation Errors
Symptoms:
- Initialization fails
IllegalArgumentExceptionerrors- Invalid parameter warnings
Solutions:
- Check parameter ranges: Ensure values are within allowed ranges
- Check required parameters: Ensure all required parameters are provided
- Check parameter types: Ensure correct data types are used
- Kotlin
- Java
// Valid parameter ranges
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}", // Required
networkTimeout = 5000, // Must be 100-10000
retryCount = 3, // Must be 0-10
printLog = true, // Boolean
errorBypass = false // Boolean
)
// Valid parameter ranges
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}", // Required
5000, // Must be 100-10000
3, // Must be 0-10
true, // Boolean
false // Boolean
);
Build & Environment Issues
ProGuard/R8 Issues
Symptoms:
- App works in debug but not release
- Class not found errors
- Method not found errors
- NetFUNNEL functions not working in release builds
Solutions:
- Add ProGuard rules: Add NetFUNNEL classes to ProGuard rules
- Check R8 configuration: Ensure R8 doesn't obfuscate NetFUNNEL classes
- Test release build: Test with release build configuration
Required ProGuard Rules:
Add these rules to your app/proguard-rules.pro file:
# NetFUNNEL Android Agent - Protect main packages and classes
-keep class com.nf4.** { *; }
# NetFUNNEL Android Agent - Keep reflection-related classes and members
-keepclassmembers class com.nf4.** { *; }
Why This Is Required:
- Release builds use code shrinking, obfuscation, and optimization
- NetFUNNEL Android Agent uses reflection and dynamic class loading
- Without these rules, NetFUNNEL classes get obfuscated and functionality breaks
- This configuration is mandatory for production releases
Testing:
- Build release APK/Bundle
- Install on device
- Test NetFUNNEL functionality
- Check Logcat for any class loading errors
Android Version Compatibility
Symptoms:
- App crashes on older Android versions
- API level compatibility errors
- Feature not available errors
Solutions:
- Check minSdk: Ensure
minSdk >= 22 - Check targetSdk: Ensure
targetSdk >= 22 - Test on devices: Test on actual devices with different Android versions
- Check API usage: Ensure using compatible APIs
Development vs Production
Symptoms:
- Works in development but not production
- Different behavior between environments
- Configuration differences
Solutions:
- Environment configuration: Use correct configuration for each environment
- Console setup: Set up separate segments for dev/prod
- Build configuration: Ensure proper build configuration
- Testing: Test both development and production builds
FAQ
Can I use both Basic Control and Section Control in the same app?
A: Yes, you can use both methods in the same application:
- Kotlin
- Java
// Basic Control for login
fun handleLogin() {
Netfunnel.nfStart("login_project", "login_segment", loginCallback, this)
}
// Section Control for checkout
fun startCheckout() {
Netfunnel.nfStartSection("checkout_project", "checkout_segment", checkoutCallback, this)
}
// Basic Control for login
public void handleLogin() {
Netfunnel.INSTANCE.nfStart("login_project", "login_segment", loginCallback, this);
}
// Section Control for checkout
public void startCheckout() {
Netfunnel.INSTANCE.nfStartSection("checkout_project", "checkout_segment", checkoutCallback, this);
}
How should I handle NetworkError?
A: Notify the user and either retry or proceed with original logic:
- Kotlin
- Java
private val callback = object : NetfunnelCallback() {
override fun onNetworkError(statusCode: Int, message: String) {
when (statusCode) {
1001 -> {
// Network not connected
showNetworkErrorDialog()
}
1002 -> {
// Network timeout - retry
retryWithDelay()
}
}
}
}
private fun retryWithDelay() {
Handler(Looper.getMainLooper()).postDelayed({
Netfunnel.nfStart(projectKey, segmentKey, callback, this)
}, 2000)
}
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
switch (statusCode) {
case 1001:
// Network not connected
showNetworkErrorDialog();
break;
case 1002:
// Network timeout - retry
retryWithDelay();
break;
}
}
};
private void retryWithDelay() {
new Handler(Looper.getMainLooper()).postDelayed(() -> {
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, this);
}, 2000);
}
What if I forget to return the key?
A: The key may be auto-returned by server timeout, but this can cause bottlenecks. Always return explicitly:
- Kotlin
- Java
// Good: Always return key
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
performAction()
.onSuccess {
Netfunnel.nfStop(projectKey, segmentKey, completeCallback)
}
.onFailure {
Netfunnel.nfStop(projectKey, segmentKey, completeCallback) // Even on error
}
}
}
// Good: Always return key
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
performAction()
.onSuccess(() -> {
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback);
})
.onFailure(() -> {
Netfunnel.INSTANCE.nfStop(projectKey, segmentKey, completeCallback); // Even on error
});
}
};
Can I initialize NetFUNNEL multiple times?
A: No, NetFUNNEL should be initialized only once in your Application class. Multiple initializations may cause unexpected behavior.
How do I debug NetFUNNEL integration?
A: Enable logging and check the logs:
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{{CLIENT_ID}}",
printLog = true // Enable logging
)
Netfunnel.INSTANCE.initialize(
"{{CLIENT_ID}}"
);
Then check Logcat for NetFUNNEL log messages.
What's the difference between Basic Control and Section Control?
A:
- Basic Control: Limits entry speed (how fast users can enter)
- Section Control: Maintains fixed concurrent user count (how many users can be active simultaneously)
Use Basic Control for simple entry limiting, Section Control for maintaining specific concurrency levels.
Can I use NetFUNNEL in a Fragment?
A: Yes, but you need to pass the Activity context:
- Kotlin
- Java
class MyFragment : Fragment() {
fun startNetFUNNEL() {
activity?.let { activity ->
Netfunnel.nfStart(projectKey, segmentKey, callback, activity)
}
}
}
public class MyFragment extends Fragment {
public void startNetFUNNEL() {
Activity activity = getActivity();
if (activity != null) {
Netfunnel.INSTANCE.nfStart(projectKey, segmentKey, callback, activity);
}
}
}
Getting Help
If you're still experiencing issues:
- Check logs: Enable
printLog = trueand check Logcat - Verify configuration: Double-check all settings in NetFUNNEL console
- Test with simple setup: Start with basic configuration and add complexity gradually
- Contact support: Reach out to NetFUNNEL support with specific error details
Related Documentation
- Quickstart: Begin quickly
- Installation & Initialization: Basic setup guide
- Integration Methods Overview: Compare Basic Control vs Section Control approaches
- Basic Control Integration: Implementation guide
- Section Control Integration: Implementation guide
- API Reference: Complete function specifications
- Configuration Options: All available options