coding etude
[Admob] admob bannerAd 로드 및 UI 구현하기 본문
Admob 페이지에서 생성 및 설정 하는 방법은 생략..
1. 설정 하기
- 파일에 앱 ID 설정하기
IOS (IOS > Runner > Info.plist)
<key>GADApplicationIdentifier</key>
<string>IOS APP ID</string>
ANDROID (android > app > src > main > AndroidManifast.xml)
<application>
<meta-data android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="Android APP ID" />
</application>
2. bannerAd 생성 및 Load 하기
처음에는 provider와 GetIt을 사용하여 생성 하고 불러와서 사용했다.
몇 가지 문제점이 발생 했다.
- watch 를 사용해서 bannerAd가 로드 되었는지 구독하는 순간 무한 리로딩을 시작한다.
(정확한 이유는 모르겠지만, bannerAd는 지속적으로 업데이트 되는듯 하다.)
- read 를 사용하여 로드하고 불러오면 bannerAd가 UI 빌드보다 늦게 로딩 됐을때 초기의 null 값을 가져오면서 UI 업데이트가 되지 않는다.
- Selector 를 사용해서 구현 했을 때 무한 로징은 없어졌지만 페이지 이동하여 다른 페이지에서도 bannerAd 를 로딩하면 이미 위젯트리에 존재하는 위젯이라면 UI 에러가 발생한다.
This AdWidget is already in the Widget tree
해결방법
1. GlobalKey를 사용하여 동일한 AdWidget를 계속 불러온다.
- bannerAd 를 생성 할 때 key 값을 GlobalKey로 지정하여 처음 요청된 bannerAd를 계속 사용하는것.
(이렇게 되면 정상작동은 하지만 모든 페이지에 하나의 배너를 돌려 쓰는것이기 때문에 수익성이 떨어질 수 있다.)
2. 모든 페이지가 빌드 될때 bannerAd를 생성해 주는 방법
- 처음에는 provider에 bannerLoader() 를 만들고 initState 에서 생성하는 방법을 사용하였는데
initState(){
super.initState()
WidgetsBinding.instance.addPostFrameCallback((_) => context.read<provider>().bannerLoad());
}
이렇게 모든 페이지에 init에서 새로 생성하는것 처럼 보이지만 사실상 동일한 bannerAd를 GetIt으로 공유하고 있다는 점과 notifyListeners() 가 불필요한 Reload를 지속적으로 발생 시키는것이 문제가 되었다.
그리고 페이지가 닫히면서 bannerAd.dispose() 를 하게되면 이전 페이지의 bannerAd 역시 dispose되면서 오류가 발생한다.
그래서 각 페이지에서 각각 로드하는 방식이 가장 안정적이고 수익성도 보장 되는 방법인듯 하다.
그러기 위해서는 AdmobHelper 클레스를 새로 만들고 Stateful로 생성 한 페이지에서 불러와야 한다.
// helper
class AdmobHelper {
BannerAd? bannerAd;
void bannerLoad(){
...
bannerAd = BannerAd(...).load();
}
}
// UI
class sample extends StatefulWidget {
...
final AdmobHelper _admobHelper = AdmobHelper();
bool _isLoaded = false
@override
initState({
_admobHelper.bannerLoad();
});
...
// UI 구현
if(_isLoaded && _admobHelper.bannerAd != null)
SizedBox(
height: _admobHelper.bannerAd.size.height,
width: _admobHelper.bannerAd.size.width,
child : AdWidget(ad : height: _admobHelper.bannerAd)
)
}
대충 이런 느낌이다. 이 설정을 모든 페이지에 설정해 주면 문제없이 동작한다.
끝.