Native Ads Integration

Native ads make it easy for you to monetize your app in a way that’s consistent with its existing design. The MoPub SDK gives you access to an ad’s individual assets so you can design the ad layout to be consistent with the look and feel of your app. The SDK automatically handles image caching and metrics tracking so you can focus on how, when, and where to display ads.


Before integrating native ads into your app:

  1. Read the Best Practices page for guidelines on how native ads can be displayed in your app.
  2. Follow the Android integration guide to integrate the MoPub SDK into your project.

Choose an Integration Option

There are three ways to integrate with the MoPubStreamAdPlacer:

Highlights of Each Method

  • Integrating with Ad Placer: The Ad Placer approach uses the MoPubStreamAdPlacer to facilitate loading native ads into an app’s content stream; for example, a scrolling list (demo). The MoPub SDK provides a MoPubAdAdapter and a MoPubRecyclerAdapter that wrap your existing adapter subclasses to insert ads into a ListView and RecyclerView, respectively.

    This approach has the advantage of letting the MoPub SDK handle automatically requesting new ads when needed, inserting them into the stream of content, and handling impression tracking and clicks. By default, three native ads will be requested and cached initially, and the SDK will request one at a time as a user scrolls through the feed. Each ad’s expiration timer starts once the ad is loaded/cached. After 4 hours, the SDK will mark these ads as ready for cleanup by the OS.

  • Integrating manually: Use this approach when the native ad placement is either a single view (demo), or is in a content stream where using the AdPlacer approach cannot fulfill specific flexibility. With this method, you will use the MoPubNative class to request and load ads. The MoPub SDK provides an AdapterHelper to retrieve a pre-populated view containing the rendered ad content and required tracking events. AdapterHelper enables you to easily add the ad view into your parent view. However, you, the publisher, will have to manually handle ad requests, ad expiration, and cases when there are no fills.

Method 1. Ad Placer (via MoPubAdAdapter)

The MoPub SDK provides the class MoPubAdAdapter, which wraps your existing Adapter subclass to insert ads into a ListView, GridView, or other view that uses an implementation of Adapter (including CursorAdapter).

This method involves these high-level steps:

  1. Set up your native ad layout.
  2. Place ads in your feed.
  3. Create a MoPubAdAdapter to wrap your existing Adapter subclass and begin loading ads.
  4. Begin loading ads.
  5. Destroy the MoPubAdAdapter.

Step 1. Set Up Your Native Ad Layout

  1. Start by defining an XML layout for how an ad should look inside your app’s feed. This example layout contains two TextViews for a title and additional text; plus three ImageViews for an icon image, a main image, and a Privacy Information icon image (demo). Choose the assets from the ad that will make it fit in most seamlessly in your app’s feed.

    • Your ad must contain the Privacy Information icon. The recommended size for this is 40dp with a 10dp padding on all sides (so the icon display area is only 20dp by 20dp, but the click area is a bit larger). This icon links to an important privacy notice, and is required for you to use MoPub’s native ads. The MoPub SDK automatically handles tap events on the privacy information icon. For example: res/layout/native_ad_layout.xml

             android:id="@+id/native_ad_main_image" />
             android:id="@+id/native_ad_icon_image" />
             android:id="@+id/native_ad_title" />
             android:id="@+id/native_ad_text" />
             android:padding="10dp" />
    • IMPORTANT: Do not set the background property on your ImageViews to null in order to handle PNG transparency gracefully as shown:

             android:background="@null" />
    • Starting with the 4.99.0 release of the Facebook Audience Network SDK, if you are mediating Facebook native ads in place of the above ImageViews, you must register Facebook’s own layouts, as shown:

       <!-- Facebook's MediaView for the main image view -->
       <!-- Facebook's AdIconView for the icon image -->
       <!-- A RelativeLayout for the AdChoices icon image from Facebook -->
           android:layout_height="40dp" />
  2. Create a ViewBinder object specifying the binding between your layout XML and the ad’s content. If you use mediation, specific ad networks might require new ViewBinder bindings for additional assets. Make sure to check the Integrating Third Party Ad Networks page for more implementation information.

     ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_ad_layout)
    • If you’re displaying direct-sold native ads, you may have additional subviews for text or images available. Add extra fields using:

      new ViewBinder.Builder().addExtras(Map<String, Integer> resIds)


      new ViewBinder.Builder().addExtra(String key, int resId)

      For example, suppose that in the MoPub Web UI you’ve added the custom fields “sponsoredtext” and “sponsoredimage”:

      "sponsoredtext" : "Sponsored",
      "sponsoredimage" : ""

      You would add these sponsored fields to your XML layout, then bind them to the view like this:

       ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_ad_layout)
         // Your custom fields are bound with the addExtra() call.
    • If you are adding an image to extras, the key must end with “image”.

  3. The MoPubAdAdapter uses a class called MoPubStaticNativeAdRenderer to load ads within your feed. Create an instance with the ViewBinder:

     MoPubStaticNativeAdRenderer adRenderer = new MoPubStaticNativeAdRenderer(viewBinder);

Step 2. Place Ads in Your Feed

Next, you’ll need to define where in your feed you’d like ads to appear using the MoPubNativeAdPositioning class to balance ads with your content. We provide server-side and client-side) positioning approaches, in which you can:

  • Specify starting positions in the feed where you always want to display ads and
  • Set the interval at which how often an ad should appear

Use this to achieve the optimal balance of ads for your app without changing your app code or releasing a new version. To set up server-side positioning:

  1. Update your native ad unit settings page. In the example below, your ads will appear in positions 1, 4, and 7 (where 0 is the position of the first row in the feed). After position 7, your ads will appear every 5 positions. Server-Side Positioning

  2. Once you’ve updated your settings in the UI, set up the MoPubNativeAdPositioning.MoPubServerPositioning object:

     MoPubNativeAdPositioning.MoPubServerPositioning adPositioning =

Option 2. Client-Side Positioning

The SDK does support setting positioning directly in the method. In this case, the position setting on ad unit page will be ignored. To set up client-side positioning:

  1. Create an MoPubClientPositioning object

     MoPubClientPositioning adPositioning = MoPubNativeAdPositioning.clientPositioning();
  2. If you want ads to appear at certain fixed positions within your feed, use addFixedPosition

  3. Use enableRepeatingPositions to instruct adapter insert ads at the specified interval as more items are loaded into your feed


Step 3. Create a MoPubAdAdapter

The MoPubAdAdapter class places the ads according to the rules set in the MoPub UI and also handles ad caching.

  1. Create an instance of MoPubAdAdapter using the current Context, your existing Adapter subclass, and the MoPubNativeAdPositioning object you created in the previous step.

     mAdAdapter = new MoPubAdAdapter(this, adapter, adPositioning);
  2. Register the ad renderer (created from your ViewBinder in step 1) so that the adapter renders your ads according to the layout you created:

  3. Set your old view’s adapter to be the new MoPubAdAdapter instance:


Step 4. Begin Loading Ads

  1. The MoPubAdAdapter is now ready to begin loading ads according to your specifications. To improve the relevance of the ads that get shown in your app, you can choose to pass up location or additional keyword data (see the data passing guide). You can also specify exactly which assets you want, to help conserve bandwidth, like so:

     final EnumSet<NativeAdAsset> desiredAssets = EnumSet.of(
                           // Don't pull the ICON_IMAGE
                           // NativeAdAsset.ICON_IMAGE,
  2. Create a new RequestParameters object using the Builder:

     mRequestParameters = new RequestParameters.Builder()
                         .location(location) // Note that, starting in v5.9.0 of the MoPub SDK, GPS location is prioritized over location data you supply from the app (i.e. when both are available, the MoPub SDK will utilize GPS location).
  3. You’re now ready to load ads, using the request parameters and the ad unit ID you created on the MoPub dashboard:

     mAdAdapter.loadAds(AD_UNIT_ID, mRequestParameters);

    Note: To test your implementation, you can also use the test ad unit ID: here. It will always return a static MoPub native creative.

    To force loading all-new ads into the stream you can call:


Step 5. Destroy the MoPubAdAdapter

The MoPubAdAdapter must be destroyed when its hosting Activity is destroyed. You should destroy the adapter in the life-cycle method that is the opposite of the method used to create the adapter. If you created the adapter in Activity.onCreate(), you should destroy it in Activity.onDestroy(). If you created the adapter in Activity.onResume(), you should destroy it in Activity.onPause().

protected void onDestroy() {

Method 2. Ad Placer (via MoPubRecyclerAdapter)

The MoPub SDK includes a RecyclerView.Adapter class called MoPubRecyclerAdapter. Using this class, you can insert ads automatically into a RecyclerView much as you do with a ListView or GridView using MoPubAdAdapter.

The SDK will handle automatically requesting new ads when needed, inserting them into the stream of content, and handling impression tracking and clicks. You can add and remove content from the RecyclerView.

Creating a MoPubRecyclerAdapter

public void onCreate(Bundle savedInstanceState) {
    // Set up your own recycler adapter
    // Set up your RecyclerView

    // Pass the recycler Adapter your original adapter.
    MoPubRecyclerAdapter myMoPubAdapter = new MoPubRecyclerAdapter(context, YOUR_OWN_ADAPTER);
    // Create an ad renderer and view binder that describe your native ad layout.
    ViewBinder myViewBinder = new ViewBinder.Builder(R.layout.my_ad_layout)

    MoPubStaticNativeAdRenderer myRenderer = new MoPubStaticNativeAdRenderer(myViewBinder);


    // Set up the RecyclerView and start loading ads

public void onDestroy() {

If you register any data observers on your original adapter, you should instead register them on the MoPubRecyclerAdapter so they will receive messages with the adjusted position of content items. If you do not do this, the positions you receive for insertion and removal messages may be inaccurate. Be sure to check isAd(position) and use MoPubRecyclerAdapter.getOriginalPosition() if you need the position of the item in your local adapter.

Manipulating RecyclerView.Adapter Content

Manipulating RecyclerView.Adapter content explains ad positioning, including:

Keeping Ads in the Same Relative Position

When adding or removing content items from your RecyclerView.Adapter, the MoPub SDK will automatically handle displaying and hiding ads as the length of the content stream changes. When adding or removing from the end, ads may appear or be hidden. When removing or inserting ads at the beginning or middle of the stream, the SDK will also adjust the ads so they remain in the same position relative to the content in the stream.

All content manipulation happens through an AdapterDataObserver that the MoPub SDK registers on your original adapter. When adding or deleting items from your stream, you should call

notifyItemsInserted(position, count);
notifyItemsRemoved(position, count);

from your adapter. You must do this so that the RecyclerView is notified to schedule a layout.

If you instead call notifyDataSetChanged when changing your content, the position of ads will not be adjusted along with your content. This is not recommended.

Keeping Ads in the Same Absolute Position

If you want MoPub to keep its ads in the same absolute position when inserting or deleting items, simply call notifyDataSetChanged() from your adapter instead of notifyItemsInserted or notifyItemsRemoved.

Advanced: ContentChangeStrategy

If you require more fine-grained control of insertion & deletion behavior with a MoPubRecyclerAdapter, you can set the ContentChangeStrategy on the adapter. The default strategy, INSERT_AT_END, behaves as described in Manipulating RecyclerView.Adapter Content.

To always keep ads in the same position, you can set the strategy to KEEP_ADS_FIXED. To always move ad positions when content is added or deleted, set the strategy to MOVE_ADS_WITH_CONTENT. You can change the strategy at any time if you require more complex ad position manipulation.

void insertOneRowAtTheEndOnTap() {

  View actionView = // Create the view.

  // Implement addItemAtEnd to call notifyItemInserted()

  // When other content is added at the end, ads can be inserted.

Method 3. Manual Integration

The manual integration involves two high-level steps:

  1. Request the native ad.
  2. Render the native ad.

We also provide some convenient helper methods.

Step 1. Request the Native Ad

  1. Create a MoPubNative instance, which will be used to register ad listeners, and ad renderers, and to make ad requests. To instantiate your MoPubNative instance, specify a Context object, an ad unit ID of type String, and a MoPubNativeNetworkListener object that will be used to listen to ad load successes/failures.

     moPubNativeNetworkListener = new MoPubNative.MoPubNativeNetworkListener() {
         // We will be populating this below
     moPubNative = new MoPubNative(this, "11a17b188668469fb0412708c3d16813 ", moPubNativeNetworkListener);

    Note: To test your implementation, you can also use the test ad unit ID: here. It will always return a static MoPub native creative.

  2. Create an XML layout, specifying how ad assets should be organized. As an example, this layout contains a standard hierarchy of our ad assets. It will be used when we create our ViewBinder in the next step.

  3. Create a ViewBinder object to bind our layout XML and the ad’s assets. We will use the XML layout referenced in step 2. If you use mediation, specific ad networks might require new ViewBinder bindings for additional assets. Make sure to check the Integrating Third Party Ad Networks page for more implementation information.

     ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_ad_list_item)

    For direct-sold native ads, you can include additional views for text or images in the ViewBinder. This is optional. You can add extra fields this way:

    ViewBinder.Builder().addExtras(Map<String, Integer> resIds) or ViewBinder.Builder().addExtra(String key, int resId)

    For example, given the below JSON that contains the following ad assets, you can expand the ViewBinder to use either addExtras() or addExtra() to append the additional asset. Note that if you are adding an image to extras, the key must end with “image”.

         "mainimage" : "",
         "iconimage" : "",
         "title" : "Sample Native Ad",
         "text" : "Sample Text",
         "sponsoredtext" : "Sponsored",
         "sponsoredimage" : ""
     ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_ad_layout)
  4. Create a MoPubStaticNativeAdRenderer with the ViewBinder just created as the argument, and register it with the MoPubNative instance. The MoPubStaticNativeAdRenderer will be used to construct and render the ad view.

     MoPubStaticNativeAdRenderer moPubStaticNativeAdRenderer = new MoPubStaticNativeAdRenderer(viewBinder);
  5. To improve the relevance of ads shown in your app, you can pass location and/or additional keyword data with the ad request. This is optional. You can also specify exactly which assets you want.

     EnumSet<RequestParameters.NativeAdAsset> desiredAssets = EnumSet.of(

    Then, create a new RequestParameters object using the Builder():

     RequestParameters mRequestParameters = new RequestParameters.Builder()
  6. Call MoPubNative.makeRequest() to request an ad from the server and download associated images asynchronously.


    You can pass in the above RequestParameters object referenced in step 5 for additional targeting.

  7. Upon success, the MoPubNativeNetworkListener.onNativeLoad() method is called with an instance of NativeAd. Upon failure, the MoPubNativeNetworkListener.onNativeFail() method is called with a corresponding error code object.

     moPubNativeNetworkListener = new MoPubNative.MoPubNativeNetworkListener() {
             public void onNativeLoad(final NativeAd nativeAd) {
                 Log.d("MoPub", "Native ad has loaded.");
             public void onNativeFail(NativeErrorCode errorCode) {
                 Log.d("MoPub", "Native ad failed to load with error: " + errorCode.toString());

    To receive callbacks for impression and click tracking, in the onNativeLoad() callback, you can register the MoPubNativeEventListener (nativeAd.setMoPubNativeEventListener(moPubNativeEventListener);), and override onImpression() and onClick(), like so:

          moPubNativeEventListener = new NativeAd.MoPubNativeEventListener() {
             public void onImpression(View view) {
                 Log.d("MoPub", "Native ad recorded an impression.");
                 // Impress is recorded - do what is needed AFTER the ad is visibly shown here.
             public void onClick(View view) {
                 Log.d("MoPub", "Native ad recorded a click.");
                 // Click tracking.

Step 2. Render the Native Ad

  1. Create an instance of AdapterHelper. You can pass in any integers as arguments for the interval:

     adapterHelper = new AdapterHelper(this, 0, 3); // When standalone, any range will be fine.

    Note: You need to use this class even though it is annotated as @Deprecated. Use it when you use AdapterHelper to retrieve a pre-populated view containing the rendered ad content and tracking events. You will need this when applying the manual integration type even for a single-view ad slot. Improper use of AdapterHelper can result in impression or click tracking issues.

  2. In your onNativeLoad callback, call AdapterHelper.getAdView() with the following parameters to get a fully populated View containing the rendered ad content. The View returned by AdapterHelper.getAdView() has a click listener attached to it, and will automatically handle opening the ad’s destination URL. It will also track impressions and clicks automatically.

      * @convertView   View    An old view to reuse, if possible, as per Adapter.getView(). If null, a new View will be inflated from XML.
      * @parent        ViewGroup   The optional parent view, which provides the correct subclass of LayoutParams for the root view’s XML.
      * @nativeAd      NativeAd    The native ad returned by the MoPub SDK. This should have been previously obtained from MoPubNativeListener.onNativeLoad(). If this is null or destroyed, the view returned will have its visibility set to View.GONE.
      * @viewBinder    ViewBinder  It's just a placeholder that is never used in this method. Should just pass in any non-null ViewBinder as below.
     public View getAdView(@Nullable final View convertView,
             @Nullable final ViewGroup parent,
             @Nullable final NativeAd nativeAd,
             @Nullable final ViewBinder viewBinder) {
     // Retrieve the pre-built ad view that AdapterHelper prepared for us.
     View v = adapterHelper.getAdView(null, nativeAdView, nativeAd, new ViewBinder.Builder(0).build());
     // Set the native event listeners (onImpression, and onClick).
     // Add the ad view to our view hierarchy

Advanced: Inserting the Native Ad into BaseAdapter Subclasses

AdapterHelper contains a few convenience methods for including native ads in a feed.

  1. Create an instance of AdapterHelper, passing in a Context, along with int start (the position of the first ad in the feed) and int interval (the frequency with which ads are shown in the feed).

    Note: You must override certain Adapter methods because including Native Ads will modify the position, number, and type of elements in the corresponding feed.

  2. Update the adapter’s getCount() to account for the addition of ads in the feed.

    Example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
     public int getCount() {
         int originalCount = super.getCount();
         return mAdapterHelper.shiftedCount(originalCount);
  3. Increment the adapter’s getViewTypeCount() method, indicating that an additional view type has been added to the adapter.

    Example (subclassing ArrayAdapter):

     int originalViewTypeCount = 2; // number of unique view types in the feed
     public int getViewTypeCount() {
         // Add 1 for native ad view type
         return originalViewTypeCount + 1;
  4. Update the adapter’s getItem() method to account for the fact that ads are being placed in the feed.

    Example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
     public T getItem(int position) {
         // Shifted position returns the original position of the content
         // in ArrayAdapter's backing array
         int shiftedPosition = mAdapterHelper.shiftedPosition(position);
         return super.getItem(shiftedPosition);
  5. Update the adapter’s getItemViewType() method to specify the positions in the feed associated with native ads.

    Example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
     private static final int EXISTING_ROW_TYPE_0 = 0;
     private static final int EXISTING_ROW_TYPE_1 = 1;
     private static final int MOPUB_NATIVE_ROW_TYPE = 2;
     public int getItemViewType(int position) {
         if (mAdapterHelper.isAdPosition(position) {
            return MOPUB_NATIVE_ROW_TYPE;
         } else {
            int shiftedPosition = mAdapterHelper.shiftedPosition(position);
            // Previous getItemViewType() logic, using shiftedPosition as the new index
  6. Update getView() to return a native ad for the appropriate feed positions.

    Example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
     View getView(int position, View convertView, ViewGroup parent) {
         if (mAdapterHelper.isAdPosition(position)) {
            return new AdapterHelper.getAdView(
         } else {
            // Previous getView() logic

Sample Code

Important Note: Avoid Excessive Ad Requests

Making requests for ads that are never displayed to the user will consume unnecessary resources and may negatively impact your revenue. Therefore, try to request ads only when they are likely to be displayed. In particular, avoid caching large quantities of ads for long periods of time.

For example, when a user initially navigates to a ListView with many rows, avoid requesting ads that will be displayed near the bottom of the ListView (that is, far below the fold). Instead, wait for the user to begin scrolling through the feed before making additional ad requests.

Last updated December 19, 2019

TWITTER, MOPUB, and the Bird logo are trademarks of Twitter, Inc. or its affiliates. All third party logos and trademarks included are the property of their respective owners.

© 2020 MoPub (a division of Twitter, Inc.)