上下文:
我使用AdMob中介在我的应用中显示横幅广告。 我整合了Millennial广告网络SDK和Millennial AdMob适配器。
问题:我的应用支持Android API 9+,而Millennial SDK支持API 16+。更糟糕的是,SDK没有优雅地失败(没有向AdMob中介层返回任何广告,以便它可以继续沿着中介瀑布走下去),SDK在运行Android<的设备上崩溃了。 16(Fatal Exception: java.lang.NoSuchMethodError
android.webkit.WebSettings.setAllowUniversalAccessFromFileURLs
)
显然,千禧一代的开发者并不打算解决这个问题,他们建议发布2个不同的APK(“没有他们的SDK”“16”,而他们的SDK使用“16+”),这是一个麻烦的解决方案。
我更喜欢更简单的解决方案:在运行Android API的设备上< 16,我想重现AdMob适配器丢失时会发生什么:AdMob中介只是转到下一个网络。 这意味着在我实例化AdMod中介横幅之前,卸载或删除 Millennial适配器类。
问题:
有没有办法在运行时阻止给定类(来自第三方库)的任何未来瞬间? (例如,通过强制ClassNotFound异常)
答案 0 :(得分:2)
使用两个广告单元。您可以在AdMob.com上设置两个横幅广告单元,一个在调解堆栈中使用MillennialMedia,另一个不在。然后,您可以在Bonatti建议的运行时检查设备的API级别,并在请求广告之前在AdView上set the ad unit ID进行检查。
如果MillennialMedia不在正在使用的广告单元的中介配置中,则Google移动广告SDK不会对其适配器进行实例化。
答案 1 :(得分:1)
我和你的情况完全相同。
经过大量的研究和类加载器的黑魔法等,我发现了一个肮脏但有效的解决方案:
// At onCreate() or wherever it makes sense
if (Build.VERSION.SDK_INT < 16) {
// Must be done before requesting the first ad
disableMMediaAdapter();
}
m_adView.loadAd(adRequest);
// ...
private void disableMMediaAdapter()
{
try {
Field fInitialized = MMSDK.class.getField("initialized");
fInitialized.setAccessible(true);
fInitialized.set(null, true);
} catch (Exception e) {
e.printStackTrace();
}
}
通过欺骗SDK使其相信它已经初始化,当通过它请求广告并且将调用下一个中介适配器时,它将很难失败。
只要他们不改变他们的课程设置太多就行了。
答案 2 :(得分:0)
有没有办法阻止在运行时给定类的任何未来瞬间? (例如,通过强制ClassNotFound异常)
您可以在加载适配器之前检查操作系统版本,以及是否低于阈值
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.THE_VERSION_I_WANT_MINIMUM) {
// doStuffs()
} else {
throw new MyException("Stuffs have stuffened...");
}