Android: can I prevent Java class from running (from an external library) at runtime

Context:

I use AdMob mediation to display banners in my application. I have included the multi-core ad network SDK and AdMob for millennia.

Problem: my application supports Android API 9+, while the Millennial SDK supports API 16+. Even worse, instead of gracefully failing (without returning the ad to the AdMob mediation level so that it can continue to go down the mediation waterfall), the SDK crashes on devices running Android <16 ( Fatal Exception: java.lang.NoSuchMethodError android.webkit.WebSettings.setAllowUniversalAccessFromFileURLs )

Apparently, Millennial developers do not plan to fix this, they recommend publishing 2 different APKs ("<16" without their SDK and "16+" with their SDK), which is a difficult decision.

I would prefer a simpler solution: on devices running the Android API <16, I would like to reproduce what happens when the AdMob adapter is missing: AdMob mediation simply moves on to the next network. This would mean unloading or erasing the Millennial adapter class before I create the AdMod mediation banner.

Question :

Is there any way to prevent the future build of this class (from a third-party library) at runtime? (for example, by forcibly excluding ClassNotFound)

+5
source share
3 answers

Use two ad units. You can set up two ad units on AdMob.com, one with MillennialMedia in the mediation stack and one without it. You can then check the device API level at runtime, as Bonatti suggests, and set the ad unit ID in your AdView, if necessary, before requesting ads.

If MillennialMedia is not included in the mediation configuration for the ad unit used, their adapter will not be created using the Google Mobile Ads SDK.

+2
source

I am exactly in the same situation as you.

After a lot of research and black magic with class loaders, etc., I found a dirty but working solution:

 // 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(); } } 

By tricking the SDK into believing that it is initialized, it will fail when the advertisement is requested through it and the next intermediary adapter is called.

This will work until they change their class too much.

+1
source

Is there a way to prevent any future installation of this class at runtime? (for example, by forcibly excluding ClassNotFound)

Before downloading the adapter, you can check the OS version and, if it is below your threshold

 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..."); } 
0
source

Source: https://habr.com/ru/post/1235359/


All Articles