There’s a severe issue we found with MoPub’s 5.2.0 MoPub.initializeSdk threading model. Here’s the full explanation we’re now sending to support@mopub.com
At some point during the MoPub initialization (with the call MoPub#initializeSdk) there is a call to MoPubIdentifier#refreshAdvertisingInfo, that in turn invokes an android AsyncTask called RefreshAdvertisingInfoAsyncTask. But that invocation is done via a call to execute() without parameters, which means that android will use the default executor for AsyncTask’s.
The history of the default executor is a complicated one. Initially it was a serial one with one single background thread, then in Donut was a parallel one with a thread pool, and finally in Honeycomb, it returned to a serial one, but based on a thread pool (and doesn’t look very robust to me). The latest means that putting blocking calls in the default executor is a guarantee of possible and sporadic problems.
Eventually, there is a call to a synchronized method MoPubIdentifier#writeIdToStorage that touch SharedPreferences, which is very problematic due to the access to the filesystem at the very early stages (to this day, we are still fighting with it in our ConfigurationManager). That could be the problem, or not, I couldn’t figure out the exact point of blocking.
If this task in the serial executor does not finish (or ends up in a dead lock), then the listener SdkInitializationListener is never invoked.
The solution was to right before calling the initializedSdk, change the default executor with the parallel one AsyncTask.THREAD_POOL_EXECUTOR, then in onInitializationFinished restore it back to AsyncTask.SERIAL_EXECUTOR. But this is a hack, since android has no public API for it.
I have the impression that they have serious multi-threading issues, but one quick solution is to them invoke executeOnExecutor with a custom executor in MoPubIdentifier#refreshAdvertisingInfo and AdvancedBiddingTokens#addAdvancedBidders.
Here’s how we patched it using java’s reflection: