SDK ์—ฐ๋™

๐Ÿ“˜

Hackle Android SDK ๋Š” Android API 16 ์ด์ƒ (4.1 Jelly Bean)์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.


์˜์กด์„ฑ ์ถ”๊ฐ€

repositories {
  mavenCentral()
}

build.gradle ํŒŒ์ผ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

dependencies {
  implementation 'io.hackle:hackle-android-sdk:2.63.0'
}

ProGuard

ProGuard๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, aar ์•„ํ‹ฐํŒฉํŠธ์— ๋‚œ๋…ํ™” ๊ทœ์น™์ด ์ž๋™์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ž˜ ๊ทœ์น™์„ ํฌํ•จ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

-keep class io.hackle.android.** { *; }
-keep class io.hackle.sdk.** { *; }

Third-party ์˜์กด์„ฑ

ํ•ตํด Android SDK๋Š” ์•„๋ž˜ third-party ์˜์กด์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์„ค๋ช…
com.squareup.okhttp3:okhttp:3.12.2HTTP/HTTPS ํด๋ผ์ด์–ธํŠธ
com.google.code.gson:gson:2.8.6JSON ์ง๋ ฌํ™”/์—ญ์ง๋ ฌํ™”
com.google.android.gms:play-services-base:17.3.0Google Play Services ๊ณตํ†ต ๋ชจ๋“ˆ


SDK ์ดˆ๊ธฐํ™”

SDK๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ๋ฐ˜๋“œ์‹œ HackleApp์„ ์ดˆ๊ธฐํ™” ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. HackleApp์„ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ ์œ„ํ•ด SDK ํ‚ค๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • HackleApp์€ SDK์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ฉ”์†Œ๋“œ๋“ค์„ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  • SDK ํ‚ค๋Š” ํ•ตํด ๋Œ€์‹œ๋ณด๋“œ ๋‚ด SDK ์—ฐ๋™ ์ •๋ณด์—์„œ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐํ™” ์‹œ ํ•ตํด ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ํ•„์š”ํ•œ ์ •๋ณด๋“ค์„ ๊ฐ€์ ธ์™€์„œ SDK์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

์ดˆ๊ธฐํ™”๋Š” ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰๋˜๋ฉฐ, ์ดˆ๊ธฐํ™” ์‹œ ๋งˆ์ง€๋ง‰ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ฝœ๋ฐฑ์„ ์ „๋‹ฌํ•˜๋ฉด SDK ์‚ฌ์šฉ ์ค€๋น„๊ฐ€ ์™„๋ฃŒ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿšง

์ดˆ๊ธฐํ™”๊ฐ€ ์™„๋ฃŒ ๋˜๊ธฐ ์ „์— A/B ํ…Œ์ŠคํŠธ, ๊ธฐ๋Šฅ ํ”Œ๋ž˜๊ทธ๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๊ธฐ๋ณธ ๊ทธ๋ฃน(A), ๊บผ์ง(false)์„ ๋ฆฌํ„ดํ•ฉ๋‹ˆ๋‹ค.

import io.hackle.android.Hackle
import io.hackle.android.initialize

Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY) {
  // SDK ready to use.
}
import io.hackle.android.HackleApp;

HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY);

๊ถŒ์žฅ ์ดˆ๊ธฐํ™” ์ „๋žต: ์Šคํ”Œ๋ ˆ์‹œ ํ™”๋ฉด์„ ํ†ตํ•œ ์ดˆ๊ธฐํ™”

์•ฑ์„ ์ฆ‰์‹œ ์‹œ์ž‘ํ•˜์ง€ ์•Š๊ณ  ์Šคํ”Œ๋ ˆ์‹œ ํ™”๋ฉด์„ ํ‘œ์‹œํ•˜๊ณ  SDK๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.
์ดํ›„ ์ฝœ๋ฐฑ์„ ํ†ตํ•ด ์Šคํ”Œ๋ ˆ์‹œ ํ™”๋ฉด์„ ๋‹ซ๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์•ฑ๊ณผ ์ƒํ˜ธ์ž‘์šฉ์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.


์ดˆ๊ธฐํ™” ์‹œ ์‚ฌ์šฉ์ž ์ฃผ์ž…

์œ ์ € ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์—ฌ SDK๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์œ ์ € ์ •๋ณด๋ฅผ ํฌํ•จํ•˜์ง€ ์•Š์œผ๋ฉด ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋œ ์œ ์ € ์ •๋ณด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ์œ ์ € ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋œ ์œ ์ € ์ •๋ณด๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž ์ฃผ์ž…์„ ํ•˜์ง€ ์•Š๊ณ , ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋œ ์œ ์ € ์ •๋ณด๋„ ์—†๋Š” ๊ฒฝ์šฐ Hackle Device ID๋ฅผ device id๋กœ ๊ฐ€์ง€๊ณ  ์œ ์ €๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๐Ÿ“˜

์œ ์ € ์ •๋ณด๋Š” SDK ์ดˆ๊ธฐํ™” ์ดํ›„์—๋„ ์œ ์ € ์ •๋ณด ์„ค์ • ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ์ž์œ ๋กญ๊ฒŒ ์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿšง

์ดˆ๊ธฐํ™” ์‹œ ์ฃผ์ž…ํ•œ ์œ ์ € ์ •๋ณด์™€ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋œ ์œ ์ € ์ •๋ณด๋Š” ๋ณ‘ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

ex) ์Šคํ† ๋ฆฌ์ง€์— userId: A ๊ฐ€ ์ €์žฅ๋œ ์ƒํƒœ์—์„œ ์ดˆ๊ธฐํ™” ์‹œ deviceId: B ๋ฅผ ์ฃผ์ž…ํ•˜๋Š” ๊ฒฝ์šฐ,
userId: null, deviceId: B์ธ ์œ ์ €๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

import io.hackle.android.Hackle
import io.hackle.android.initialize
import io.hackle.sdk.common.User

let user = User.builder()
    .userId("142")                  // ์‚ฌ์šฉ์ž ID
    .deviceId("ae2182e0")           // ๋””๋ฐ”์ด์Šค ID
    .build()

Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY, user) {
  // SDK ready to use.
}
import io.hackle.android.HackleApp;
import io.hackle.sdk.common.User

User user = User.builder()
    .userId("142")                  // ์‚ฌ์šฉ์ž ID
    .deviceId("ae2182e0")           // ๋””๋ฐ”์ด์Šค ID
    .build()

HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY, user, () -> {
  // SDK ready to use.
});

์ดˆ๊ธฐํ™” ์„ค์ •์ •๋ณด

์„ค์ •์ •๋ณด๋ฅผ ํฌํ•จํ•˜์—ฌ SDK๋ฅผ ์ดˆ๊ธฐํ™” ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import io.hackle.android.Hackle
import io.hackle.android.HackleConfig
import io.hackle.android.initialize

val config = HackleConfig.builder()
  .build()
 
Hackle.initialize(applicationContext, YOUR_APP_SDK_KEY, config) {
  // SDK ready to use.
}
import io.hackle.android.HackleApp;
import io.hackle.android.HackleConfig;

HackleConfig config = HackleConfig.builder()
  .build();

HackleApp.initializeApp(getApplicationContext(), YOUR_APP_SDK_KEY, config, () -> {
  // SDK ready to use.
});

์„ค์ • ์˜ต์…˜

์„ค์ •

๊ธฐ๋Šฅ

๊ธฐ๋ณธ๊ฐ’

์ง€์› ๋ฒ„์ „

exposureEventDedupIntervalMillis

๋™์ผํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์—ฐ์†์œผ๋กœ ๋ฐœ์ƒ์‹œํ‚จ ๋™์ผํ•œ A/B ํ…Œ์ŠคํŠธ, ๊ธฐ๋Šฅํ”Œ๋ž˜๊ทธ ๋ถ„๋ฐฐ๊ฒฐ๊ณผ์— ๋Œ€ํ•œ ๋…ธ์ถœ ์ด๋ฒคํŠธ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

์ตœ์†Ÿ๊ฐ’: 1000 (1์ดˆ) ์ตœ๋Œ“๊ฐ’:

  • ~2.46.1 : 3600000 (1์‹œ๊ฐ„)
  • 2.47.0~ : 8640000(24์‹œ๊ฐ„)

60000 (1๋ถ„)

2.7.0+ (2.47.0 ์ดํ›„๋ถ€ํ„ฐ ์•ฑ ์ข…๋ฃŒ ํ›„ ์žฌ์‹œ์ž‘ ์‹œ์—๋„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.)

eventFlushIntervalMillis

์ˆ˜์ง‘๋œ ์ด๋ฒคํŠธ๋ฅผ ์„œ๋ฒ„๋กœ ์ „์†กํ•˜๋Š” ์ฃผ๊ธฐ์ž…๋‹ˆ๋‹ค.

์ตœ์†Ÿ๊ฐ’: 1000 (1์ดˆ) ์ตœ๋Œ“๊ฐ’: 60000 (1๋ถ„)

10000 (10์ดˆ)

2.10.0+

sessionTimeoutMillis

์„ธ์…˜๋งŒ๋ฃŒ ์‹œ๊ฐ„์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

1800000 (30๋ถ„)

2.13.0+

pollingIntervalMillis

๋Œ€์‹œ๋ณด๋“œ์—์„œ ์„ค์ •ํ•œ ์ •๋ณด๋ฅผ ์ฃผ๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ตœ์†Ÿ๊ฐ’ : 60000 (60์ดˆ)

-1 (์ฃผ๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธํ•˜์ง€ ์•Š์Œ)

2.19.0+

automaticScreenTracking

ํ™”๋ฉด ์ž๋™ ์ถ”์  ํ™œ์„ฑํ™” ์—ฌ๋ถ€

true

2.39.0+

automaticAppLifecycleTracking

์•ฑ ์‹œ์ž‘ / ์ข…๋ฃŒ ์ž๋™ ์ถ”์  ํ™œ์„ฑํ™” ์—ฌ๋ถ€

true

2.64.0+


์ธ์Šคํ„ด์Šค ๊ฐ€์ ธ์˜ค๊ธฐ

์ดˆ๊ธฐํ™” ์ดํ›„ ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด HackleApp ์ธ์Šคํ„ด์Šค๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import io.hackle.android.Hackle
import io.hackle.android.app

val hackleApp = Hackle.app
import io.hackle.android.HackleApp;

HackleApp hackleApp = HackleApp.getInstance();

๋Œ€์‹œ๋ณด๋“œ ์„ค์ • ์ •๋ณด ๊ฐฑ์‹ 

์ดˆ๊ธฐํ™” ์ดํ›„ ๋Œ€์‹œ ๋ณด๋“œ ์„ค์ • ์ •๋ณด ๊ฐฑ์‹ ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋ช…์‹œ์ ์œผ๋กœ ๊ฐฑ์‹  ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿšง

ํ•ด๋‹น ํ•จ์ˆ˜๋Š” 60์ดˆ์— ํ•œ๋ฒˆ ์ œํ•œ์ ์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

hackleApp.fetch {
  // done
}
hackleApp.fetch(new Runnable() {
    @Override
    public void run() {
        // done
    }
});