今天从源码角度分析一下mopub,
以下内容基于Mopub 5.12.0 Android源码,github上可以下载到,通过阅读源码,理清逻辑,找到自己想要的答案。
1.初始化入口
MoPub.initializeSdk(mContext, sdkConfiguration, initSdkListener());
Mopub.java类第175行initializeSdk方法;
作用,初始化mopub SDK;在请求激励广告或者bidding前调用该方法,这个方法将对自定义adpater调用任意次数,但是SDK自己仅仅初始化一次。
第178行~184行,检测context,sdkConfiguration是否为空,打印log
第185行~190行,判断Application info是否为空,然后打印日志
第191行~195行,初始化激励视频 initializeRewardedVideo(activity, sdkConfiguration);
Mopub.java类第357行~375行,是initializeRewardedVideo
第358行~360行,检测activity,sdkConfiguration是否为空
第362行~366行,通过Reflection.MethodBuilder
new Reflection.MethodBuilder Reflection.java类中,第34行~45行;确定反射类名,initializeRewardedVideo setStatic("com.mopub.mobileads.MoPubRewardedVideos"), 设定反射修饰符为static setAccessible 设定mIsAccessible,设定访问权限
addParam,传入当前activity
addParam,传入当前sdkConfiguration
execute方法,98行~118行;获取class名;方法名,添加参数;判断是否Accessible,是否Static;然后执行method.invoke(如何执行sdkConfiguration传入进来的参数)
第367行~375行,捕获反射的异常
第196行~200行,如果mopub已经初始化完毕,向外抛initializationFinished回调,
第201行~205行,如果mopub正在初始化,直接return掉
第206行~210行,判断当前线程是否是主线程,mopub只能在主线程初始化
第211行~215行;设置正在初始化的标记位为true;确保当前的请求在主线程
第216行~221行,定义两个final sdk初始化状态的监听类
第389行~407行,静态类InternalSdkInitializationListener,主要作用,当收到sdk初始化完成的回调,向上抛,sdk初始化完成的回调。就是初始化mopubsdk的第3个参数。
类CompositeSdkInitializationListener,的作用是,将初始化的回调,合并,一次发送。(这个类写的很巧妙,可以学习下)
定义了一个mTimes参数,当收到一次回调,这个次数就减1,当mTimes小于等于0时,就触发向外抛初始化成功的回调。
@Override
public void onInitializationFinished() {
mTimes--;
if (mTimes <= 0) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
if (mSdkInitializationListener != null) {
mSdkInitializationListener.onInitializationFinished();
mSdkInitializationListener = null;
}
}
});
}
}
第222行~第225行,实例PersonalInfoManager类,处理用户个人信息,如GDPR,等
第226行,单例获取ClientMetadata,用户手机,网络等相关信息;单例用的双重校验锁 DCL
第227行~第233行,实例化AdapterConfigurationManager,通过异步线程获得bidding相关数据,并存储到内存中,供后面查询调用。
2.Mopub加载激励视频入口
MopubRewardedVideos.loadRewardedVideo(rewardedId, new MopubRewardedVideoManager.RequestParameters(null,null));
MopubRewardedVideos.class
第47-52行,loadRewardedVideo,
49行,检查传进来的参数是否为空,Preconditions.checkNotNull(adUnitId);
50行,加载激励视频,MopubRewardedVideoManager.loadVideo(adUnitId, requestParameters, mediationSettings);
MopubRewardedVideoManager.class
第176-209行,加载激励视频
178-180行,检查单例是否为空,空就报错
181-184行,如果当前播放广告的id,和传进来的广告id相同,那么就打印log,不再向下执行
184-194行,如果当前缓存的广告id和传进来的广告id相同,那么就对外发送广告已加载的回调,不再向下执行
195-209行,加载广告
206行,加载激励广告,loadVideo(adUnitId,(String)urlGenerator.generateUrlString(Constants.HOST), (MoPubErrorCode)null)
211-217行,加载激励视频,sInstance.fetchAd(adUnitId, adUrlString, errorCode)
219-226行,加载激励视频,判断当前id是否正在加载;rewardedAdsLoaders.loadNextAd(mContext, adUnitId, adUrlString, errorCode);
RewardedAdsLoaders.class
32-43行,loadNextAd,
37-40行,判断adLoader是否为空,adLoader是否有已经缓存的广告,空或者无广告,就执行mAdUnitToAdLoader.put(adUnitId, adLoader);
42行,adloader.loadNextAd(errorCode);执行加载的逻辑
AdLoader.java 广告加载核心类
133-219行,loadNextAd方法,waterfall的逻辑主要是在loadNextAd方法中实现的,广告是异步加载的,广告可能来自内部缓存或者从服务端下载。请确保调用加载广告前,调用hasMoreAds方法
175行,fetchAd(mMultiAdRequest, mContext.get());//第一次请求
260-287行,通过网络库请求
3.加载核心位置
AdLoader.java 第175行fetchAd(mMultiAdRequest, mContext.get());//first request 第一次请求
268行,fetchAd()方法 283-286行,RequestQueue request =Networking.getRequestQueue(context); 通过Volley进行请求
Networking.java 98行 requestQueue = new MoPubRequestQueue(cache, network);
MopubRequestQueue.java 58行,addDelayedRequest(@NonNull Request> request, int delayMs)
addDelayedRequest(request, new DelayedRequestHelper(request, delayMs));
RequestManager.java 60行, makeRequest(@NonNull T requestFactory, @NonNull BackoffPolicy backoffPolicy)