Rewarded Ads

Integrate CloudX rewarded ads in Android apps

Rewarded ads give users a reward — typically in-app currency or bonus content — in exchange for watching a fullscreen ad.

CloudX-rendered creatives

CloudX-served creatives are rendered by the built-in renderer, which ships inside the core SDK — no separate renderer adapter module is required. The creative type is selected automatically from the bid response, so no publisher integration is needed to render either format. The renderer supports MRAID 3.0 (HTML) and VAST creatives across the ad formats:

Ad formatHTML (MRAID 3.0)VAST
Banner
MREC
Interstitial
Rewarded
class MainActivity : AppCompatActivity(), CloudXRewardedListener, CloudXAdRevenueListener {
    private lateinit var rewardedAd: CloudXRewardedAd
    private var retryAttempt = 0

    private fun createRewardedAd() {
        rewardedAd = CloudX.createRewarded(this, "your-rewarded-ad-unit-id")
        rewardedAd.listener = this
        rewardedAd.revenueListener = this
        rewardedAd.load()
    }

    private fun showRewardedAd() {
        if (rewardedAd.isAdReady) {
            // Basic show
            rewardedAd.show(this)

            // Or with optional placement and custom data for tracking
            // rewardedAd.show(this, "bonus_coins", "level:5,coins:100")
        } else {
            Log.w("CloudX", "Rewarded ad not ready yet")
        }
    }

    // CloudXRewardedListener callbacks
    override fun onAdLoaded(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Rewarded ad loaded from ${cloudXAd.networkName}")
        retryAttempt = 0
    }

    /**
     * Retries loading with exponential backoff: delay doubles with each attempt
     * (2s → 4s → 8s … 32s max) to avoid hammering the server during transient
     * failures. [retryAttempt] resets to 0 in [onAdLoaded].
     */
    override fun onAdLoadFailed(adUnitId: String, cloudXError: CloudXError) {
        Log.e("CloudX", "Rewarded ad failed to load: ${cloudXError.message}")
        retryAttempt++
        val delayMillis = TimeUnit.SECONDS.toMillis(2.0.pow(retryAttempt.coerceAtMost(5)).toLong())
        Handler(Looper.getMainLooper()).postDelayed({ rewardedAd.load() }, delayMillis)
    }

    override fun onAdDisplayed(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Rewarded ad displayed")
    }

    override fun onAdDisplayFailed(cloudXAd: CloudXAd, cloudXError: CloudXError) {
        Log.e("CloudX", "Rewarded ad failed to display: ${cloudXError.message}")
        rewardedAd.load()
    }

    override fun onAdHidden(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Rewarded ad hidden")
        // Reload for next use
        rewardedAd.load()
    }

    override fun onAdClicked(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Rewarded ad clicked")
    }

    override fun onUserRewarded(cloudXAd: CloudXAd, reward: CloudXReward) {
        Log.d("CloudX", "User rewarded: ${reward.amount} ${reward.label}")
        // Grant the reward to the user
    }

    // CloudXAdRevenueListener callback
    override fun onAdRevenuePaid(cloudXAd: CloudXAd) {
        Log.d("CloudX", "Rewarded bid-time revenue: ${cloudXAd.revenue} from ${cloudXAd.networkName}")
    }

    override fun onDestroy() {
        super.onDestroy()
        rewardedAd.destroy()
    }
}