Android 네트워크 에러 대응
이 문서는 NetFUNNEL Android 에이전트 사용 중 발생할 수 있는 네트워크 에러를 식별하고, 상황에 맞는 처리 방법과 우회 옵션, 복구 기능을 설정하는 방법을 안내합니다.
1. 네트워크 에러 콜백
NetFUNNEL Android 에이전트는 네트워크 에러 발생 시 onNetworkError 콜백을 통해 에러 상황을 전달합니다.
1.1 네트워크 에러 종류
onNetworkError는 대기 시작 전, 또는 대기 중 네트워크 문제가 발생할 경우 호출됩니다.
| 상태 코드 | 메시지 | 설명 |
|---|---|---|
| 1001 | Network Not Connected | 네트워크 연결 차단 (와이파이, 셀룰러 데이터 차단) |
| 1002 | Network Timeout | 네트워크 응답 지연으로 인한 시간 초과 |
1.2 네트워크 에러 콜백 예시
네트워크 에러 발생 시, statusCode에 따라 분기 처리하여 사용자에게 안내하거나 재시도 화면으로 전환할 수 있습니다.
- 1001 (네트워크 연결 차단): 사용자가 네트워크 연결 상태를 확인해야 하므로, 알림창 등으로 즉시 안내
- 1002 (네트워크 시간 초과): 네트워크 지연이 회복될 가능성이 있으므로 에러 화면으로 유도
- Kotlin
- Java
import com.nf4.Netfunnel
import com.nf4.NetfunnelCallback
import android.util.Log
import android.widget.Toast
import android.content.Intent
// ...
override fun onNetworkError(statusCode: Int, message: String) {
Log.d(TAG, "onNetworkError $statusCode $message")
when (statusCode) {
1001 -> {
activity.runOnUiThread {
Toast.makeText(activity, "Network connection failed. Please check your network settings.", Toast.LENGTH_SHORT).show()
}
}
1002 -> {
// Switch to the retry screen
val intent = Intent(activity, NetworkErrorActivity::class.java)
activity.startActivity(intent)
}
}
}
import com.nf4.Netfunnel;
import com.nf4.NetfunnelCallback;
import android.util.Log;
import android.widget.Toast;
import android.content.Intent;
import androidx.annotation.NonNull;
// ...
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
Log.d(TAG, "onNetworkError " + statusCode + " " + message);
switch (statusCode) {
case 1001:
activity.runOnUiThread(() ->
Toast.makeText(activity, "Network connection failed. Please check your network settings.", Toast.LENGTH_SHORT).show()
);
break;
case 1002:
// Switch to the retry screen
Intent intent = new Intent(activity, NetworkErrorActivity.class);
activity.startActivity(intent);
break;
}
}
네트워크 에러 처리 예제
import android.content.Intent
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.nf4.NetfunnelCallback
class StartCallback(private val activity: AppCompatActivity) {
companion object {
private const val TAG = "NetFUNNEL"
}
val callback = object : NetfunnelCallback() {
// ... other callback implementations like onSuccess, onError
override fun onNetworkError(statusCode: Int, message: String) {
Log.d(TAG, "onNetworkError $statusCode $message")
when (statusCode) {
1001 -> activity.runOnUiThread {
Toast.makeText(activity, "Could not connect to the network.", Toast.LENGTH_SHORT).show()
}
1002 -> {
val intent = Intent(activity, NetworkErrorActivity::class.java).apply {
putExtra("projectKey", "{{PROJECT_KEY}}")
putExtra("segmentKey", "{{SEGMENT_KEY}}")
}
activity.startActivity(intent)
}
}
}
}
}
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.nf4.Netfunnel
import com.your.package.name.databinding.ActivityNetworkErrorBinding
class NetworkErrorActivity : AppCompatActivity() {
private lateinit var binding: ActivityNetworkErrorBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityNetworkErrorBinding.inflate(layoutInflater)
setContentView(binding.root)
val projectKey = intent.getStringExtra("projectKey")
val segmentKey = intent.getStringExtra("segmentKey")
binding.btnRetry.setOnClickListener {
if (projectKey != null && segmentKey != null) {
val startCallback = StartCallback(this)
Netfunnel.nfStart(projectKey, segmentKey, startCallback.callback, this)
finish() // Finish the current error screen
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Network Connection Error"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Network connection is unstable.\nPlease try again later."
android:textAlignment="center" />
<Button
android:id="@+id/btn_retry"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="Retry" />
</LinearLayout>
2. 네트워크 관련 설정
NetFUNNEL Android 에이전트는 네트워크 환경에 유연하게 대응하기 위한 설정들을 제공합니다.
2.1 retryCount
retryCount는 네트워크 요청 실패 시, 자동으로 재시도하는 횟수입니다.
| 항목 | 내용 |
|---|---|
| 목적 | 일시적 네트워크 오류에 대한 자동 재시도 |
| 기본값 (회) | 0 |
| 최솟값 (회) | 0 |
| 최댓값 (회) | 10 |
| 동작 방식 | retryCount 횟수만큼 내부 재시도 후, 실패 시 onNetworkError 호출 |
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
retryCount = 3
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
null, // serverUrl
null, // errorUrl
3000L, // networkTimeout
3, // retryCount
false, // printLog
false, // errorBypass
true, // useNetfunnelTemplate
null, // userId
false, // useNetworkRecoveryMode
null, // healthCheckUrl
null // statusBarStyle
);
retryCount: 3으로 설정하면, 최초 요청 실패 시 최대 3회까지 추가로 재시도합니다. 요청이 중간에 성공하면 재시도는 중단됩니다.
2.2 networkTimeout
networkTimeout은 네트워크 응답을 기다리는 최대 시간을 설정합니다.
| 항목 | 내용 |
|---|---|
| 목적 | 요청 지연 또는 서버 무응답 상황을 빠르게 탐지 |
| 기본값 (ms) | 3000 |
| 최솟값 (ms) | 100 |
| 최댓값 (ms) | 10000 |
| 동작 방식 | networkTimeout만큼 네트워크 응답을 기다린 후, 네트워크 실패 결정 |
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
networkTimeout = 5000L // 5 seconds
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
null, // serverUrl
null, // errorUrl
5000L, // networkTimeout
0, // retryCount
false, // printLog
false, // errorBypass
true, // useNetfunnelTemplate
null, // userId
false, // useNetworkRecoveryMode
null, // healthCheckUrl
null // statusBarStyle
);
networkTimeout: 3000 설정 시, 35ms 내 오류 응답이 오더라도 2.965초 뒤 재시도합니다.
networkTimeout=3000, retryCount=3 설정 시 최대 12초 이후 onNetworkError 콜백이 호출됩니다.
너무 짧은 값으로 설정할 경우, 정상적인 요청도 타임아웃으로 처리될 수 있습니다.
2.3 healthCheckUrl
healthCheckUrl은 네트워크 에러 발생 시, 설정된 URL로 Health Check를 수행하여 단순 네트워크 지연인지, NetFUNNEL 서버 장애인지 구분합니다.
| 항목 | 내용 |
|---|---|
| 기본값 | null |
| 설명 |
|
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
healthCheckUrl = "https://your-server.com/health"
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
null, // serverUrl
null, // errorUrl
3000L, // networkTimeout
0, // retryCount
false, // printLog
false, // errorBypass
true, // useNetfunnelTemplate
null, // userId
false, // useNetworkRecoveryMode
"https://your-server.com/health", // healthCheckUrl
null // statusBarStyle
);
3. 우회 관련 설정
3.1 errorBypass
errorBypass는 네트워크 요청을 실패하더라도 onNetworkError 콜백 대신 onSuccess 콜백을 호출하여, 서비스 진입을 허용합니다.
| 항목 | 내용 |
|---|---|
| 기본값 | false |
| 예시 |
|
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
errorBypass = true
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
null, // serverUrl
null, // errorUrl
3000L, // networkTimeout
0, // retryCount
false, // printLog
true, // errorBypass
true, // useNetfunnelTemplate
null, // userId
false, // useNetworkRecoveryMode
null, // healthCheckUrl
null // statusBarStyle
);
errorBypass=true 설정 시 onError와 onNetworkError 대신 onSuccess 상태값이 반환되기 때문에 필수 구현해야 하는 상태값은 onSuccess가 유일합니다.
errorBypass=true 설정은 모든 에러 상황을 우회 처리하므로, 사용 시 주의가 필요합니다.
4. 복구 관련 설정
4.1 useNetworkRecoveryMode
useNetworkRecoveryMode는 대기 중 네트워크 요청이 실패해도 대기실을 유지하며, 지속적으로 네트워크 연결을 시도합니다.
| 항목 | 내용 |
|---|---|
| 기본값 | false |
| 참고 | 사용하지 않을 경우, 대기 중 네트워크 요청을 실패하면 대기실이 닫히고 onNetworkError 콜백 호출 |
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
useNetworkRecoveryMode = true
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
null, // serverUrl
null, // errorUrl
3000L, // networkTimeout
0, // retryCount
false, // printLog
false, // errorBypass
true, // useNetfunnelTemplate
null, // userId
true, // useNetworkRecoveryMode
null, // healthCheckUrl
null // statusBarStyle
);
useNetworkRecoveryMode=true 설정은 대기 중 네트워크가 끊긴 경우에만 대기실을 유지합니다. 대기 시작 전에 네트워크가 끊긴 경우, onNetworkError 콜백이 호출됩니다.