Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/197.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:我可以防止Java类(来自外部库)在运行时被实例化吗_Java_Android_Admob - Fatal编程技术网

Android:我可以防止Java类(来自外部库)在运行时被实例化吗

Android:我可以防止Java类(来自外部库)在运行时被实例化吗,java,android,admob,Java,Android,Admob,上下文: 我使用AdMob中介在我的应用程序中显示横幅广告。 我集成了Millennial ad network SDK和Millennial AdMob适配器 问题:我的应用程序支持Android API 9+,而千禧SDK支持API 16+。更糟糕的是,SDK在运行Android

上下文:

我使用AdMob中介在我的应用程序中显示横幅广告。 我集成了Millennial ad network SDK和Millennial AdMob适配器

问题:我的应用程序支持Android API 9+,而千禧SDK支持API 16+。更糟糕的是,SDK在运行Android<16(
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时引发异常。