Files
2nd/10_Wiki/Topics/Coding/Native_Battery_Network_Profiling.md
T
2026-05-09 21:08:02 +09:00

4.3 KiB

id, title, category, status, source_trust_level, verification_status, created_at, updated_at, tags, tech_stack, applied_in, aliases
id title category status source_trust_level verification_status created_at updated_at tags tech_stack applied_in aliases
native-battery-network-profiling Battery / Network Profiling — 사용량 줄이기 Coding draft B conceptual 2026-05-09 2026-05-09
native
battery
network
profiling
vibe-coding
language applicable_to
Swift / Kotlin
iOS
Android
battery drain
network usage
doze
background fetch
WorkManager

Battery / Network Profiling

모바일 앱 = 배터리 + 데이터 모두 한정. 하루 5% 이상 소모면 사용자 삭제. wake lock / 백그라운드 polling / GPS / sync 4종이 주범. 측정 → 줄이기.

📖 핵심 개념

  • Doze (Android): screen off + 정지 → background 제한.
  • Background app refresh (iOS): OS 가 사용 패턴 학습 → 자유로 결정.
  • Wake lock: CPU 끄기 막음. 마지막 수단.
  • Network bytes: cellular/wifi 별 측정.

💻 코드 패턴

Android — Battery Historian

adb bugreport bugreport.zip
# https://bathist.ef.lc/ 에 업로드 또는 로컬 docker
docker run -p 9999:9999 bhaavan/battery-historian

iOS — Energy Log

Xcode → Open Developer Tool → Instruments → Energy Log
# 또는 디바이스: Settings → Privacy → Analytics → Logs

Network — 사용량 측정

// Android: TrafficStats / NetworkStatsManager
val rx = TrafficStats.getUidRxBytes(android.os.Process.myUid())
val tx = TrafficStats.getUidTxBytes(android.os.Process.myUid())
// iOS: URLSessionTaskMetrics 로 본인 트래픽 측정
class M: NSObject, URLSessionTaskDelegate {
    func urlSession(_ s: URLSession, task: URLSessionTask, didFinishCollecting m: URLSessionTaskMetrics) {
        for tx in m.transactionMetrics {
            print("\(tx.request.url!): \(tx.countOfRequestBodyBytesSent) tx, \(tx.countOfResponseBodyBytesReceived) rx")
        }
    }
}

백그라운드 작업 — WorkManager (Android)

val req = PeriodicWorkRequestBuilder<SyncWorker>(15, TimeUnit.MINUTES)
    .setConstraints(
        Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED) // wifi 만
            .setRequiresCharging(false)
            .setRequiresBatteryNotLow(true)
            .build()
    )
    .build()

WorkManager.getInstance(ctx).enqueueUniquePeriodicWork("sync", KEEP, req)

iOS — BGTaskScheduler

BGTaskScheduler.shared.register(
    forTaskWithIdentifier: "com.app.refresh",
    using: nil
) { task in handleRefresh(task as! BGAppRefreshTask) }

let r = BGAppRefreshTaskRequest(identifier: "com.app.refresh")
r.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(r)

Network 압축 / batch

// OkHttp 자동 gzip
// 또는 brotli interceptor 추가

// Batch: 5초 마다 모아서 한 번 POST 보다 좋은 게 있나? 응 — 즉시 + jitter 분산

위치 (가장 비싼 자원)

val req = LocationRequest.Builder(BALANCED_POWER_ACCURACY, 60_000) // 1분 + 협력적
    .setMinUpdateDistanceMeters(50f) // 50m 변화만
    .build()
let m = CLLocationManager()
m.desiredAccuracy = kCLLocationAccuracyHundredMeters
m.distanceFilter = 100
// significant change service
m.startMonitoringSignificantLocationChanges()

🤔 의사결정 기준

작업 권장
Background sync WorkManager (Android) / BGTaskScheduler (iOS)
Push 보다 polling 항상 push 가 우월 (FCM/APNs)
위치 추적 Significant change / geofence (지속 추적 X)
큰 다운로드 Background URLSession / WorkManager unmetered
Wake lock 단기 + 명시적 release

안티패턴

  • Background 5초 polling: 배터리 폭발.
  • GPS continuous high accuracy: 분당 5%.
  • Wake lock 잡고 release 안 함: 영구 켜짐.
  • Cellular 에서 큰 동기화: 데이터 폭발. unmetered 조건.
  • Image 원본 다운로드: thumbnail / WebP / AVIF.
  • WebSocket 평생 유지: foreground 만, background 는 push.
  • JSON 비압축: gzip + minify.

🤖 LLM 활용 힌트

  • WorkManager / BGTaskScheduler 항상 사용.
  • 위치는 significant / geofence.
  • 측정 → push, batch, 압축 3종.

🔗 관련 문서