Android:我可以防止Java类(来自外部库)在运行时被实例化吗
上下文: 我使用AdMob中介在我的应用程序中显示横幅广告。 我集成了Millennial ad network SDK和Millennial AdMob适配器 问题:我的应用程序支持Android API 9+,而千禧SDK支持API 16+。更糟糕的是,SDK在运行Android<16(Android:我可以防止Java类(来自外部库)在运行时被实例化吗,java,android,admob,Java,Android,Admob,上下文: 我使用AdMob中介在我的应用程序中显示横幅广告。 我集成了Millennial ad network SDK和Millennial AdMob适配器 问题:我的应用程序支持Android API 9+,而千禧SDK支持API 16+。更糟糕的是,SDK在运行Android
Fatal Exception:java.lang.NoSuchMethodError)的设备上崩溃,而不是正常地失败(不向AdMob中介层返回ad,以便它可以继续沿着中介瀑布运行)
android.webkit.WebSettings.setAllowUniversalAccessFromFileURL
)
显然,千禧一代开发人员不打算解决这个问题,他们建议发布两个不同的APK(“
是否有任何方法可以防止将来在运行时实例化给定类?(例如,通过强制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...");
}
使用两个广告单元。您可以在AdMob.com上设置两个横幅广告单元,一个在中介堆栈中有MillennialMedia,另一个没有。然后,您可以按照Bonatti的建议,在运行时检查设备的API级别,并在请求广告之前根据需要在AdView上进行检查
如果MillennialMedia不在正在使用的ad单元的中介配置中,则其适配器将不会被Google Mobile Ads SDK实例化。我的情况与您完全相同 在对类加载器等进行了大量研究和黑魔法之后,我发现了一个肮脏但有效的解决方案:
// 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();
}
}
//在onCreate()或任何有意义的地方
如果(Build.VERSION.SDK_INT<16){
//必须在请求第一个广告之前完成
禁用MediaAdapter();
}
m_adView.loadAd(adRequest);
// ...
私有无效禁用MediaAdapter()
{
试一试{
字段fInitialized=MMSDK.class.getField(“已初始化”);
fInitialized.setAccessible(true);
fInitialized.set(null,true);
}捕获(例外e){
e、 printStackTrace();
}
}
通过诱使SDK相信它已初始化,当通过它请求ad时,它将失败,并调用下一个中介适配器
只要他们不太改变类设计,这就行。这个类上已经有构造函数了吗?如果没有,实现一个默认构造函数(没有参数)这会引发您的异常。@dotvav是的,类
MillennialAdapter
有一个构造函数,由AdMob中介库调用。我可以通过反编译适配器类并对其进行修改来达到我的目的,但我想避免这种情况。哦,那么您的意思是防止将来实例化一个类*您无法控制*。这不容易er是否只检查操作系统版本以不使用低于最低sdk的admob?这里有一些关于Java类卸载或重新加载的提示可能会有所帮助:抱歉,如果我的问题不清楚,但这并不能回答问题。重要的一点是不检查操作系统版本,而是从外部库禁用类。此解决方法可以解决问题b、 但这对我来说并不令人满意:我的主要广告单元ID的中介瀑布中有很多广告网络,每个网络都有一些特定于国家的CPM设置,我会定期手动更新。复制这个广告单元会使更新中介设置的过程几乎延长一倍……有趣的方法!最终我成功了解决方案是反编译他们的SDK,并添加SDK检查以在API<16时引发异常。