4.3 KiB
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 |
|
|
|
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종.