Android 통합 가이드
통합 가이드는 NetFUNNEL Android 에이전트를 실제 서비스에 안정적으로 통합하기 위한 전체 구현 과정을 단계별로 설명합니다.
1. 에이전트 소개
NetFUNNEL Android 에이전트는 모바일 어플리케이션에서 NetFUNNEL 서버와 통신하는 전용 클라이언트입니다. 사용자는 적용하고자 하는 클라이언트 어플리케이션 코드에 에이전트에서 제공하는 다양한 함수들을 적용, 구현하여 가상 대기실을 적용할 수 있습니다.
1.1 최소 요구 사항
Android API Level 22 (Lollipop 5.1) 이상
Java 1.8 이상
Kotlin 1.9.0 이상
1.2 외부 의존성
Ktor (2.1.0 이상, 3.0.0 미만)
Kotlinx Serialization (버전 무관)
2. 에이전트 설치
본 가이드는 Android Studio 환경을 기준으로 작성합니다.
2.1 에이전트 다운로드
에이전트 파일을 다운로드 합니다.
2.2 .aar 파일 추가
제공된 .aar파일을 프로젝트의 app/libs 디렉터리에 복사합니다.
project_root/
├── app/
│ └── libs/
│ ├── netfunnel-android-agent-release-{{latest}}.aar
│ ├── netfunnel-android-agent-debug-{{latest}}.aar
└── gradle/
2.3 Gradle 설정
2.3.1 에이전트 종속성 추가
NetFUNNEL Android 에이전트는 빌드 환경에 따라 총 2개의 파일을 제공합니다. 디버깅 시에는 debug 사용을 권장하며, 앱 배포 시 release 사용을 권장합니다.
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
dependencies {
implementation(files("libs/netfunnel-android-agent-release-{{latest}}.aar"))
...
}
dependencies {
implementation files('libs/netfunnel-android-agent-release-{{latest}}.aar')
...
}
2.3.2 외부 라이브러리 추가
NetFUNNEL Android 에이전트는 외부 라이브러리를 포함하지 않습니다. 아래 라이브러리를 프로젝트에 추가합니다.
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
dependencies {
val ktorVersion = "{{KTOR_VERSION}}"
val serializationVersion = "{{SERIALIZATION_VERSION}}"
// Ktor dependencies
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")
// Serialization dependency
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion")
...
}
ext {
ktorVersion = "{{KTOR_VERSION}}"
serializationVersion = "{{SERIALIZATION_VERSION}}"
}
dependencies {
// Ktor dependencies
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"
// Serialization dependency
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVersion"
...
}
2.3.3 Gradle 환경 설정
- Kotlin DSL (build.gradle.kts)
- Groovy DSL (build.gradle)
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
}
}
予算
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
}
}
2.4 Manifest 설정
NetFUNNEL 서버와 통신하기 위해 인터넷 사용 권한을 추가해야 합니다. AndroidManifest.xml 파일에서 인터넷 접속 권한을 허용합니다.
- AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Allow internet access permission -->
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
3. 에이전트 초기화
NetFUNNEL Android 에이전트는 앱 실행과 동시에 초기화되어야 합니다.
Application 클래스의 onCreate()에서 앱 시작 시 한 번만 실행될 수 있도록 초기화 작업을 수행합니다.
3.1 초기화 함수 호출
- Kotlin
- Java
Netfunnel.initialize(
clientId = "{CLIENT_ID}",
serverUrl = "{{SERVER_URL}}",
errorUrl = "{{ERROR_URL}}",
networkTimeout = 3000,
retryCount = 0,
printLog = false,
errorBypass = false,
useNetfunnelTemplate = true,
userId = "{{USER_ID}}",
useNetworkRecoveryMode = true,
healthCheckUrl = "{{HEALTH_CHECK_URL}}",
statusBarStyle = null
)
Netfunnel.INSTANCE.initialize(
"{CLIENT_ID}",
"{{SERVER_URL}}",
"{{ERROR_URL}}",
3000,
0,
false,
false,
true,
"{{USER_ID}}",
true,
"{{HEALTH_CHECK_URL}}",
null
);
3.2 Manifest 수정
생성한 Application 클래스는 AndroidManifest.xml에 name을 등록합니다.
- AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- Register Application name -->
<application
android:name=".SampleApplication"
android:allowBackup="true">
</application>
</manifest>
3.3 초기화 파라미터 상세
statusBarStyle 웹뷰 상태바에 대한 세부 내용은 고급 기능 - 대기실 상태바 설정에서 확인하세요.
| 파라미터 | 타입 | 설명 | 조건 | 필수 |
|---|---|---|---|---|
| clientId | String | 사용자를 식별하기 위한 고유 ID | 빈 문자열 불가 | O |
| serverUrl | String | 넷퍼넬 서버 주소 | 없음 (기본 주소 사용) | X |
| errorUrl | String | 에러 발생 시 표시할 에러 페이지의 주소 | 없음 (기본 주소 사용) | X |
| networkTimeout | Long | 서버 응답을 기다리는 최대 시간 (ms 단위) |
| X |
| retryCount | Int | 네트워크 요청 실패 시 자동 재시도 횟수 |
| X |
| printLog | Boolean | 디버깅을 위한 로그 출력 여부 | 기본: false | X |
| errorBypass | Boolean | 에러 발생 시 대기실 바이패스 여부 | 기본: false | X |
| useNetfunnelTemplate | Boolean | 넷퍼넬 콘솔에서 설정한 대기실 템플릿 사용 여부 | 기본: true | X |
| userId | String | 화이트리스트/블랙리스트 확인 시 사용하는 end-user 식별자 | 기본: null | X |
| useNetworkRecoveryMode | Boolean | 대기 중 네트워크가 끊기더라도 재연결을 시도하며 대기실을 유지할지 여부 | 기본: false | X |
| healthCheckUrl | String | 네트워크 지연과 넷퍼넬 서버 장애를 구분하기 위한 헬스체크용 URL | 기본: null | X |
| statusBarStyle | String | 넷퍼넬 대기실(WebView)의 상태바 스타일 | 기본: null | X |
4. 에이전트 적용
시작 함수와 종료 함수에 사용하는 프로젝트 키와 세그먼트 키는 콘솔의 프로젝트 탭에서 확인 가능합니다.
4.1 콜백 함수
NetFUNNEL Android 에이전트를 사용하기 위해서는 시작 함수와 종료 함수에 콜백 함수를 반드시 주입해야 합니다. 대기실은 다양한 상황(대기 성공, 취소, 차단, 에러, 네트워크 오류 등)에 따라 종료될 수 있으며, 각 상황에 대한 처리 시나리오는 콜백 함수를 통해 구현할 수 있습니다.
| abstract class | abstract function | 필수 구현 여부 |
|---|---|---|
| NetfunnelCallback | onSuccess | 필수 |
| NetfunnelCallback | onError | 필수 |
| NetfunnelCallback | onNetworkError | 필수 |
| NetfunnelCallback | onBlock | 선택 |
| NetfunnelCallback | onClose | 선택 |
| NetfunnelCallback | onContinue | 선택 |
| NetfunnelCompleteCallback | onComplete | 선택 |
4.1.1 시작 콜백 - NetfunnelCallback
onNetworkError 네트워크 에러에 대한 세부 내용은 고급 기능 - 네트워크 에러 대응에서 확인하세요.
onContinue 자체 커스텀 대기실에 대한 세부 내용은 고급 기능 - 넷퍼넬 대기실 미사용에서 확인하세요.
| 콜백 함수 | 상태 코드 | 시나리오 |
|---|---|---|
| onSuccess | 200 |
|
| onSuccess | 300 |
|
| onSuccess | 303 |
|
| onError | 500 |
|
| onNetworkError | 1001 |
|
| onNetworkError | 1002 |
|
| onBlock | 301 |
|
| onBlock | 302 |
|
| onClose | 495 |
|
| onClose | 496 |
|
| onClose | 497 |
|
| onClose | 498 |
|
| onClose | 499 |
|
| onContinue | 201 |
|
- Kotlin
- Java
import com.nf4.NetfunnelCallback
class StartCallback {
companion object {
private const val TAG = "NetFUNNEL"
}
private val callback = object : NetfunnelCallback() {
override fun onSuccess(statusCode: Int, message: String) {
Log.d(TAG, "onSuccess $statusCode $message")
/**
* Logic to handle when the queue is successfully passed
* e.g., Navigate to the service screen
*/
}
override fun onError(statusCode: Int, message: String) {
Log.d(TAG, "onError $statusCode $message")
/**
* Logic to handle errors
* e.g., Display an error message to the user or bypass
*/
}
override fun onNetworkError(statusCode: Int, message: String) {
Log.d(TAG, "onNetworkError $statusCode $message")
/**
* Logic to handle network errors
* e.g., Guide the user to reconnect or navigate to a retry screen
*/
}
override fun onBlock(statusCode: Int, message: String) {
Log.d(TAG, "onBlock $statusCode $message")
/**
* Logic to handle when user access is blocked
* e.g., Display an access restriction message
*/
}
override fun onClose(statusCode: Int, message: String) {
Log.d(TAG, "onClose $statusCode $message")
/**
* Logic to handle when the user cancels the queue (automatically returns to the previous screen upon WebView closure)
* e.g., Display a cancellation notice Toast
*/
}
override fun onContinue(statusCode: Int, message: String, aheadWait: Int, behindWait: Int, waitTime: String, progressRate: Int) {
Log.d(TAG, "onContinue $statusCode $message")
/**
* Logic to update the UI during queue progress (applies only when using a custom queue screen)
* e.g., Update the custom queue screen with real-time queue information
*/
}
}
fun getCallback(): NetfunnelCallback = callback
}
import com.nf4.NetfunnelCallback;
public class StartCallback{
private static final String TAG = "NetFUNNEL";
private final NetfunnelCallback callback = new NetfunnelCallback() {
@Override
public void onSuccess(int statusCode, @NonNull String message) {
Log.d(TAG, "onSuccess " + statusCode + " " + message);
/**
* Logic to handle when the queue is successfully passed
* e.g., Navigate to the service screen
*/
}
@Override
public void onError(int statusCode, @NonNull String message) {
Log.d(TAG, "onError " + statusCode + " " + message);
/**
* Logic to handle errors
* e.g., Display an error message to the user or bypass
*/
}
@Override
public void onNetworkError(int statusCode, @NonNull String message) {
Log.d(TAG, "onNetworkError " + statusCode + " " + message);
/**
* Logic to handle network errors
* e.g., Guide the user to reconnect or navigate to a retry screen
*/
}
@Override
public void onBlock(int statusCode, @NonNull String message) {
Log.d(TAG, "onBlock " + statusCode + " " + message);
/**
* Logic to handle when user access is blocked
* e.g., Display an access restriction message
*/
}
@Override
public void onClose(int statusCode, @NonNull String message) {
Log.d(TAG, "onClose " + statusCode + " " + message);
/**
* Logic to handle when the user cancels the queue (automatically returns to the previous screen upon WebView closure)
* e.g., Display a cancellation notice Toast
*/
}
@Override
public void onContinue(int statusCode, @NonNull String message, int aheadWait, int behindWait, @NonNull String waitTime, int progressRate) {
Log.d(TAG, "onContinue " + statusCode + " " + message);
/**
* Logic to update the UI during queue progress (applies only when using a custom queue screen)
* e.g., Update the custom queue screen with real-time queue information
*/
}
};
public NetfunnelCallback getCallback() {
return callback;
}
}
4.1.2 종료 콜백 - NetfunnelCompleteCallback
| 콜백 함수 | 상태 코드 | 시나리오 |
|---|---|---|
| onComplete | 200 | 대기 완료 후 서버에 진입 키 반납을 성공한 경우 |
| onComplete | 500 | 대기 완료 후 서버에 진입 키 반납을 실패한 경우 |
- Kotlin
- Java
import com.nf4.NetfunnelCompleteCallback
class StopCallback {
companion object {
private const val TAG = "NetFUNNEL"
}
private val callback = object : NetfunnelCompleteCallback() {
override fun onComplete(statusCode: Int, message: String) {
Log.d(TAG, "onComplete $statusCode $message")
/**
* Logic to handle the result of entry key return
* e.g., Navigate to the next page upon successful key return
*/
}
}
fun getCallback(): NetfunnelCompleteCallback = callback
}
import com.nf4.NetfunnelCompleteCallback;
public class StopCallback {
private static final String TAG = "NetFUNNEL";
private final NetfunnelCompleteCallback callback = new NetfunnelCompleteCallback() {
@Override
public void onComplete(int statusCode, @NonNull String message) {
Log.d(TAG, "onComplete " + statusCode + " " + message);
/**
* Logic to handle the result of entry key return
* e.g., Navigate to the next page upon successful key return
*/
}
};
public NetfunnelCompleteCallback getCallback() {
return callback;
}
}
4.2 기본 제어
4.2.1 시작 함수
특정 화면(Activity 혹은 Fragment)에서 대기실을 적용시키기 위해서는 에이전트에서 제공하는 "대기 시작 함수"를 사용하여 가상 대기실을 노출시킬 수 있습니다. 기본 제어는 end-user가 특정 화면에 진입할 때 대기를 적용하여 서버 부하를 조절하고, end-user 경험을 관리하는 데 유용합니다.
- Kotlin
- Java
Netfunnel.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity)
Netfunnel.INSTANCE.nfStart("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity);
| 파라미터 | 타입 | 설명 | 필수 여부 |
|---|---|---|---|
| projectKey | String | 콘솔의 기본 제어 프로젝트 키 | O |
| segmentKey | String | 콘솔의 기본 제어 세그먼트 키 | O |
| callback | NetfunnelCallback | 대기실 이벤트 처리를 위한 사용자 정의 콜백 함수 | O |
| activity | Activity | 대기실 적용시키는 화면 | O |
4.2.2 종료 함수
- Kotlin
- Java
Netfunnel.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
Netfunnel.INSTANCE.nfStop("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
| 파라미터 | 타입 | 설명 | 필수 여부 |
|---|---|---|---|
| projectKey | String | 대기 시작 함수에 사용한 프로젝트 키 | O |
| segmentKey | String | 대기 시작 함수에 사용한 세그먼트 키 | O |
| completeCallback | NetfunnelCompleteCallback | 대기를 마치고 키 반납을 처리하기 위한 사용자 정의 콜백 함수 | O |
4.3 구간 제어
4.3.1 시작 함수
- Kotlin
- Java
Netfunnel.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity)
Netfunnel.INSTANCE.nfStartSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", callback, activity);
| 파라미터 | 타입 | 설명 | 필수 여부 |
|---|---|---|---|
| projectKey | String | 콘솔의 구간 제어 프로젝트 키 | O |
| segmentKey | String | 콘솔의 구간 제어 세그먼트 키 | O |
| callback | NetfunnelCallback | 대기실 이벤트 처리를 위한 사용자 정의 콜백 함수 | O |
| activity | Activity | 대기실 적용시키는 화면 | O |
4.3.2 종료 함수
- Kotlin
- Java
Netfunnel.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback)
Netfunnel.INSTANCE.nfStopSection("{{PROJECT_KEY}}", "{{SEGMENT_KEY}}", completeCallback);
| 파라미터 | 타입 | 설명 | 필수 여부 |
|---|---|---|---|
| projectKey | String | 대기 시작 함수에 사용한 프로젝트 키 | O |
| segmentKey | String | 대기 시작 함수에 사용한 세그먼트 키 | O |
| completeCallback | NetfunnelCompleteCallback | 대기를 마치고 키 반납을 처리하기 위한 사용자 정의 콜백 함수 | O |
FAQ
HTTP 통신 시 오류가 발생해요
A: NetFUNNEL Android 에이전트는 기본적으로 HTTPS 통신을 권장하며, HTTP 통신을 사용할 경우 Android 보안 정책에 따라 오류가 발생합니다.
- `res/xml/network_security_config.xml` 파일 생성
- 네트워크 보안 정책 XML 파일을 `AndroidManifest.xml`에 등록
콜백 함수에서 UI 업데이트하고 싶어요
A: 콜백 함수 사용 중 UI 업데이트가 필요할 때에는 주의가 필요합니다. 비동기로 동작하는 NetFUNNEL 콜백 함수 내에서 Toast 같은 UI 요소를 직접 호출하면 java.lang.NullPointerException 오류가 발생할 수 있습니다. 따라서, 넷퍼넬 콜백 함수를 사용할 때에는 Activity.runOnUiThread(Runnable) 메소드를 사용하여 UI를 업데이트를 비동기 스레드에서 메인 스레드로 전환하여 사용해야 합니다.
디버깅용 로그 메시지를 확인하고 싶어요
A: 디버깅을 위해 NetFUNNEL Android 에이전트에서 발생하는 로그 메시지를 확인하는 방법은 다음과 같습니다.1. 초기화 함수의 printLog=true 설정2. Android Studio의 Logcat에 package:mine NetFUNNEL을 통해 확인디버깅 시에는 printLog 값을 true로 사용하길 권장하나, 앱 배포 시 false 사용을 권장합니다.
난독화로 인해 오류가 발생해요
A: 앱 배포 시 코드 축소, 난독화, 최적화를 하는 경우, NetFUNNEL Android 에이전트는 제외되어야 합니다. 이를 위해 proguard-rules.pro 프로가드 규칙 파일에 아래 내용을 포함시켜 난독화에서 제외시킬 수 있습니다.
에이전트 버전을 확인하고 싶어요
A: 에이전트의 버전을 확인하기 위해 getVersion() 함수를 사용할 수 있습니다.