← Back to list

GAID(Google Advertise Id) 사용 시 크래시 피하기

Google Advertise 라이브러리를 통해 광고 id를 사용할 때 크래시를 피하는 방법을 알아봅니다

hongbeom in hongbeomi dev · 2025-03-03 08:29 · 9 claps · 5.7 min read
#android #android-studio #google-admob #gaid #advertising-id
Open on Medium ↗

GAID(Google Advertise Id) 사용 시 크래시 피하기

Google Advertise 라이브러리를 통해 광고 id를 사용할 때 크래시를 피하는 방법을 알아봅니다

Photo by Kate Trysh on Unsplash

Photo by Kate Trysh on Unsplash

우리가 만든 앱의 수익화를 위해 흔히 Google AdMob을 활용하여 광고를 부착하곤 합니다. 이때 광고 개인화 등의 목적으로 사용자를 고유하게 식별하려면 identifier API를 통해 id에 접근할 수 있습니다. 하지만 공식 가이드 문서대로 id를 사용할 경우, 사용자에게 크래시가 발생할 수 있습니다.

가이드 문서에서 공개된 API는 getAdvertisingIdInfo 하나뿐이므로, 아래와 같은 API를 사용하여 id를 가져올 수 있습니다.

fun getAdvertisingId(context: Context) {
  scope.launch {
    withContext(Dispatchers.IO) {
      // Main Thread로 접근 시 크래시
      val info = AdvertisingIdClient.getAdvertisingIdInfo(context)
      val advertiseId = info.id 
      ...
    }
  }
}

그러나 이러한 방식으로 사용할 경우, 시스템 메모리가 부족하여 우리의 앱이 다른 앱보다 우선순위가 낮아 종료되었다가 다시 사용자가 앱에 돌아와서 id에 접근하려하면 크래시가 발생할 수 있습니다. 이를 확인하기 위해 간단한 버튼을 추가하고, id를 출력하는 UI를 구성해보겠습니다.

// Activity
class MainActivity : ComponentActivity() {

  private val viewModel by viewModels<MainViewModel>()

  override fun onCreate(savedInstanceState: Bundle?) {
    ...
    setContent {
      ...
      val context = LocalContext.current
      val id by viewModel.advertiseId.collectAsStateWithLifecycle()
      Column(...) {
        Button(onClick = { viewModel.getAdvertisingId(context) }) {
          Text(text = "Get Google Advertising Id")
        }
        Spacer(modifier = Modifier.height(16.dp))
        Text(text = id.toString(), fontSize = 28.sp)
      }
    }
  }
  ...
}

// ViewModel
class MainViewModel : ViewModel() {

  val advertiseId = MutableStateFlow<String?>(null)

  fun getAdvertisingId(context: Context) {
    viewModelScope.launch {
      withContext(Dispatchers.IO) {
        val info = AdvertisingIdClient.getAdvertisingIdInfo(context)
        advertiseId.value = info.id
      }
    }
  }
}

일반적인 상황에서는 문제없이 id에 접근할 수 있습니다. 그러나 메모리 부족과 같은 상황을 재현해보기 위해 개발자 모드에서 활동 유지 안 함 옵션을 활성화하고 백그라운드 프로세스 수를 없음으로 설정한 뒤 다른 앱으로 이동했다가 빠르게 앱으로 돌아오면 id에 접근할 수 없게 되고 이내 크래시가 발생합니다.

getAdvertisingIdInfo 내부에서 뭔가 이미 파괴된 객체를 참조하여 발생하는 오류로 보이는데, 이 객체는 우리가 파라미터로 넘겨준 Context라고 추정해볼 수 있습니다. AdvertisingIdClient 클래스 내부를 살펴보겠습니다.

public static Info getAdvertisingIdInfo(
  @NonNull Context context
) throws IOException, 
IllegalStateException, 
GooglePlayServicesNotAvailableException,
GooglePlayServicesRepairableException {

  AdvertisingIdClient var1 = new AdvertisingIdClient(context, -1L, true, false);
  ...
  context1 = var1.zzd(-1);
  ...
}

private final Info zzd(int param1) throws IOException {
  // $FF: Couldn't be decompiled
}

내부적으로 Client 객체를 생성하고 zzd라는 함수를 호출하는데, 이 함수는 난독화되어 있어 내부를 알 수가 없습니다.🥲

해당 객체를 새로 생성하여 이전 참조를 끊어지게 해줄 경우 해결할 수 있는 문제라고 생각하던 중, AdvertisingIdClient의 생성자가 public으로 제공되므로 이를 활용할 수 있었습니다. AdvertisingIdClient 객체를 생성자를 통해 직접적으로 생성한 후, start 함수를 호출하여 작업을 새롭게 실행하도록 코드를 수정했습니다.

fun getAdvertisingId(context: Context) {
  viewModelScope.launch {
    withContext(Dispatchers.IO) {
      val client = AdvertisingIdClient(context)
      client.start()
      advertiseId.value = client.info.id
    }
  }
}

이제 매번 새로운 AdvertisingIdClient 객체를 생성하고, 새로운 객체에 대한 참조를 유지하기 때문에 위 재현 과정에서도 크래시가 발생하지 않습니다🎉

가끔 간헐적으로 발생할 수 있는 문제이므로 크게 크리티컬하진 않지만, 이를 방지하면 더 나은 사용자 경험을 제공할 수 있을 것입니다.


메타데이터
post_id
9e8b327036d8
slug
gaid-google-advertise-id-사용-시-크래시-피하기-9e8b327036d8
url
https://medium.com/hongbeomi-dev/gaid-google-advertise-id-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%ED%81%AC%EB%9E%98%EC%8B%9C-%ED%94%BC%ED%95%98%EA%B8%B0-9e8b327036d8
canonical_url
https://medium.com/hongbeomi-dev/gaid-google-advertise-id-%EC%82%AC%EC%9A%A9-%EC%8B%9C-%ED%81%AC%EB%9E%98%EC%8B%9C-%ED%94%BC%ED%95%98%EA%B8%B0-9e8b327036d8
author_url
https://medium.com/@hongbeomi
status
ok
fetched_at
2026-06-20 20:29:01