Monetization Android¶
Managing the size of the Flurry SDK on Android¶
When building large Android apps, there are two different aspects of an Android libraries size that might be of a concern.
The first, and least common, is the disk space/memory the library would occupy, measured in bytes.
The second, and more common, is the number of methods the library contains.
With regards to the Flurry SDK, the first issue is not a problem because the entire Flurry ads and analytics SDK only adds about 300 KB to an app, which is minuscule given the high availability of disk space and memory on devices today. The second issue is a more common developer complaint when they have an already large app that is relying on multiple libraries to function. With an app already using multiple libraries, adding any more library functionality could get difficult on Android.
On Android, the platform’s build architecture creates .dex files from an application that the platform’s runtime can execute. These .dex files have a limit on the number of methods that it can contain. By default, each app will have one .dex file and each .dex file can only contain about 65K methods. However, when a developer’s app starts depending on a lot of libraries, it can be very easy to go beyond that 65K method limit, resulting in an error like the following when the app is built:
Conversion to Dalvik format failed: Unable to execute dex: method ID not in [0, 0xffff]: 65536
…or on newer platforms:
trouble writing output: Too many field references: 131000; max is 65536. You may try using –multi-dex option.
Consider that the Flurry SDK alone adds 5K methods for the ads API and ~2K methods for the analytics and Tumblr API as of version 6.0.0. This means that including the Flurry SDK will take ~10% of a developer’s allowed method count. Including other libraries and the application’s own code, it is possible to see how a developer can easily approach the 65K method limit, especially when they include the entire Google Play Services library, which currently has over 20K methods.
There are several ways to overcome this limit. Each of the ways listed below are also available when using the Flurry SDK.
Remove unused code or selectively compile Google Play Services
Many large applications easily suffer from having leftover legacy code. This legacy code could add to the method count of apps and removing them would reduce not just the app’s method count, but also its build time.
Legacy code is not the only code that could be unused in an app, however. Sometimes, developers may include library dependencies that their app does not really need. This could be as a result of oversight or using a boilerplate template to build the apps. One large culprit of an unused library dependency is Google Play Services (GPS). As mentioned above, GPS can easily add over 20K methods to your app.
On Android Studio, developers now have the option of only including the parts of GPS that they need, instead of including the entire 20K methods. To do that, they can modify their build.gradle file.
Assuming they had the following build.gradle snippet:
- dependencies {
compile ‘com.google.android.gms:play-services:7.5.0’
}
This would include the entire GPS library. Instead, they can break down the snippet to include only parts that they need:
- dependencies {
compile ‘com.google.android.gms:play-services-analytics:7.5.0’ compile ‘com.google.android.gms:play-services-ads:7.5.0’ compile ‘com.google.android.gms:play-services-maps:7.5.0’
}
The methods described above are not a fireproof solution. There are two drawbacks:
You need to be using Gradle or Android Studio to be able to selectively compile GPS. Apps built with Eclipse without Gradle cannot do this. This method assumes that it is the unused code that is taking the app over the DEX method limit. It is possible to have only code that is used, but still go over the method limit.
Using ProGuard
ProGuard allows you minimize your application by removing unused or unreferenced code during the build process. In this case, ProGuard is doing the same thing described in the previous method, but automatically. When building Android apps, ProGuard is not enabled by default, so enabling ProGuard, the app developer may be able to go below the method limit.
There are some drawbacks to ProGuard:
ProGuard will only reduce the method count based on the amount of code used in the app. It only attempts to remove unused code. If the app does use a lot of code and dependencies it has, ProGuard may not be able to go below the DEX limit. ProGuard may sometimes remove code that is used. In this case, the developer will need to configure ProGuard to specify what parts of code is used.
Multidexing
As mentioned earlier, each Android app contains one executable .dex file by default. Multidexing allows you split an app to contain multiple .dex files, with each file having its own method limit.
This method is the only guaranteed way to go below the limit and should be the default recommendation to Flurry app developers. Configuration for multidexing is easy on Maven or Gradle build supported systems like Android Studio.
However, multidexing will not work for every app. Here are some drawbacks:
Only works for IDEs or build systems that use Maven or Gradle, like Android Studio or IntelliJ. Eclipse is not supported. Applications that target Android APIs lower than version 14 will need to specifically test their apps with API 14 or less as multidexing could cause the app to not start or crash during startup on those levels. Using multiple .dex files may slow down an application’s startup time. Not all libraries may allow multidexing. The Flurry SDK allows multidexing, but other included libraries that use native code or invocation may not easily allow for multidexing. This case is rare, but may arise in some cases where the developer is using Java libraries not built for Android.
Dynamic Class Loading or using DexClassLoader
This is the most complicated of all the listed methods and it requires that the developer have a separate .dex file for different libraries that do not add to their own app’s .dex file. The library .dex files can then be loaded dynamically, while the app is running. Because the libraries are not included at build time, the app will then need to use reflection to access the libraries’ APIs.
Due to the complexity and brittleness of this method, this method is discouraged for Flurry app developers, but it is allowed by the Flurry SDK.
The disadvantages of this method are:
Complexity in setting up. Because the app will need to use reflection at runtime to access library APIs, the app would be very brittle. If there is an update to a library, there is no way to know how any API changes will affect the app when building the app. The developer will have to go through the app documentation and change their reflection implementation to fit with the new APIs.
Overall, the size of the Flurry SDK should not be a problem to most modern apps as there are several easy solutions to overcome the DEX method limit. The recommendation to Flurry app developers should be to start by using ProGuard and removing unused code and dependencies. If that doesn’t put the app under the limit, Multidexing will work for most setups. Dynamic class loading should only be used in rare cases.
ssl support¶
As of Flurry Android SDK 5.3, the ssl is the default transport mechanism and setSecureTransportEnabled method has been removed as no longer necessary.
Does Flurry support Android Advertising Id?¶
With the release of 4.0.0 version Flurry Advertising uses the Android Advertising ID provided by Google Play Services. The SDK will check for and respect the user’s ad tracking preference.
The google-play-services_lib needs to be a referenced library when building a project with FlurryAds_5.x.x.jar. For more information on Android Advertising ID please follow this link
No Ads served: I have followed your integration instructions, but see no ads in my app.¶
A couple of quick pointers on how to troubleshoot the lack of ads:
Verify the ad unit name in your code is the same capitalization as the ad unit configured on the flurry dev portal
Check the ad unit object as coded (FlurryAdNative, FlurryAdInterstitial, or FlurryAdBanner) matched the ad unit type (Stream, Full Screen, Banner Top or Banner Bottom) as defined on the flurry dev portal
Check the ad unit is configured to serve ads. On the flurry dev portal go to Monetization tab, on the left hand navigation bar select Applications & Ad Units, and select the ad unit in question. In the section Advanced Options make sure that Gemini Backfill, RTB Marketplace Backfill, or both is set to On to ensure Yahoo is sending you the ads. This is relevant for the Stream and Full Screen placements. The Banner placements can only have the RTB Marketplace Backfill setting.
Turn the Flurry logging on in your app and observe the output for the Flurry related statements.
- When integrating banners, interstitials or native ad spaces, look at the callbacks that
FlurryAdBannerListener, FlurryAdInterstitialListener or FlurryAdNativeListener respectively, return upon calling fetchAd on the ad object. Each of the three delegates returns the adequately named version of the onError callback. Namely:
Each error callback provides the FlurryAdErrorType and the errorCode that you can look into to understand the cause for the failure to receive the ad object.
The external error codes that can be returned to your app are as follows:
Error code |
Error summary |
Error description |
---|---|---|
1 |
No network connectivity |
There is no internet connection |
2 |
Missing ad controller |
Occurs when ad has not been prepared |
3 |
No context |
A valid context is missing |
4 |
Invalid ad unit |
The ad unit that is used is invalid. |
17 |
Ad not ready |
Triggered when you call displayAd() on an ad object that is not ready |
18 |
Wrong orientation |
Device is in wrong orientation for banner or interstitial ads |
19 |
No view group |
Banner ad wasn’t placed in a ViewGroup |
20 |
Ad was unfilled |
No ads available from server for this space |
21 |
Incorrect class for ad space |
Ad request made with incorrect class for corresponding ad space |
22 |
Device locked |
Device is locked during ad request |
Similarly each delegate fires a callback in case the ad object is received:
If you are working with FlurryAdBanner object, and the onFetched callback is received, but the ad is not displayed, check your layout to see if the viewGroup parameter as provided when creating the FlurryAdBanner(Context context, ViewGroup viewGroup, String adSpace) object is incorporated into the layout.
Android Error Codes¶
The external error codes that can be returned to your app are as follows:
Error code |
Error summary |
Error description |
---|---|---|
1 |
No network connectivity |
There is no internet connection |
2 |
Missing ad controller |
Occurs when ad has not been prepared |
3 |
No context |
A valid context is missing |
4 |
Invalid ad unit |
The ad unit that is used is invalid. |
17 |
Ad not ready |
Triggered when you call displayAd() on an ad object that is not ready |
18 |
Wrong orientation |
Device is in wrong orientation for banner or interstitial ads |
19 |
No view group |
Banner ad wasn’t placed in a ViewGroup |
20 |
Ad was unfilled |
No ads available from server for this space |
21 |
Incorrect class for ad space |
Ad request made with incorrect class for corresponding ad space |
22 |
Device locked |
Device is locked during ad request |
FlurryAds: No ads available from server for this space.¶
There are few reasons for this error, some are temporary some are reflection on geographical availability of Flurry ads. You can (temporarily) set your ad space into the test mode to see if the ads appear - see here how to set the test mode.. The test mode is available for Gemini ads only. The ads served from the RTB marketplace are not available in the test mode. The test mode is not available for banner ads.
Please do remember to turn the test mode off prior to submitting your app to the Play Store.
No Ads on the lock screen¶
Flurry SDK prevents ads being displayed on the lock screen. This behavior is by design: our native ads are paid per the viewable impression. As we find hard to assure that the ads served on the lock screen are actually seen by the users we have decided to disable this option.
How does my app know if an ad is available ?¶
For each fetchAd called on an object, its respective listener (FlurryAdBannerListener, FlurryAdInterstitialListener or FlurryAdNativeListener ) returns either onFetched or onError callback. In case onFetched is returned, the ad object is the parameter of this callback.
We recommend calling isReady() on the ad object to verify if the ad is ready prior to displaying it.
onVideoCompleted delegate is not called¶
void onVideoCompleted(FlurryAdInterstitial adInterstitial)
listener callback method will be
called when a video finishes playing to inform the app that a video
associated with an ad has finished playing.
This method is invoked for Rewarded full screen takeover ad units only (this includes the following ad mix options: Rewarded, Client-side Rewarded). The ad unit configured as Standard ad mix will not invoke this delegate. See further instructions to integrate rewards into your app.
Can I control what ads show in an Ad Unit?¶
You can filter out the ads from showing in your Ad Unit by setting filters under the Filters. Filters (BlackLists) are available for app store id, advertiser name and app name.
You can set up filters for a specific Ad Unit and copy those settings to another ad unit. Under Blacklists > Copy Blacklists form another Ad Unit, you will see a drop down on the right to select the Ad Unit that you’d like to copy the filters from.
Ad Unit Test mode¶
Setting an ad unit into the test mode is meant to help you validate the integration. The test mode removes any content or geo filtering and delivers the ads into the ad space.
You can (temporarily) set your interstitial ad unit into the test mode to validate your integration.
or the same setting applied for your native ad unit
Please do remember to turn the test mode off prior to submitting your app to the App Store.
Or you can configure your ad unit to send the test ads to a particular device used for integration testing. To do so, on the flurry dev portal go to Monetization tab, on the left hand navigation bar select Applications & Ad Units, and select the ad unit in question. In the Advanced Options section, in the Test Device IDs field enter the Android Advertising Id of the test device where you are verifying the integration code.

My game is in Unity, can I integrate Flurry ads into my game?¶
Flurry provided Unity plugin currently supoprts Flurry analytics only, see further instructions how to integrate Unity plugin.
How do I get the sponsored icon/advertiser name to display when mediating native ads with MoPub?¶
To include the icon, you have to add it as a MoPub extra. When building your MoPub native renderer, modify your code to look like this: