Native Ads (Manual)

Native ads let you 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.

Prerequisites

Before integrating native ads into your app:

  1. Create an account on MoPub and integrate the MoPub SDK into your project.
  2. Read our Best Practices article for guidelines about displaying native ads in your app.

Integrate Native Ads Manually Using MoPubNative

Choose this option when the native ad placement is either a single view or in a content stream, where using the AdPlacer approach cannot meet specific flexibility needs. With this option, you 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 must manually handle ad requests, ad expiration, and cases when there are no fills.

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 is 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);
    
  2. Create an XML layout, specifying how ad assets should be organized. 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 may require new ViewBinder bindings for specific assets.

     ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_ad_list_item)
        .mainImageId(R.id.native_main_image)
        .iconImageId(R.id.native_icon_image)
        .titleId(R.id.native_title)
        .textId(R.id.native_text)
        .privacyInformationIconImageId(R.id.native_privacy_information_icon_image)
        .addExtra("sponsoredimage", R.id.sponsored_image) // If you display direct-sold native ads, you can add additional subviews for custom assets
        .build();
    
    • If you add an image via addExtra(), the key must end with image.

    • Starting with MoPub SDK v5.11.0, the Advertiser name is available in the sponsored text field. We recommend using “Sponsored by” or localized versions when this string is returned. Example:

      <string name="com_mopub_nativeads_sponsored_by">Sponsored by %s</string>
      
  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);
     moPubNative.registerAdRenderer(moPubStaticNativeAdRenderer);
    
  5. To improve the relevance of ads shown in your app, you can optionally pass in additional keyword data to the ad request. You can also specify exactly which assets you want.

     EnumSet<RequestParameters.NativeAdAsset> desiredAssets = EnumSet.of(
                RequestParameters.NativeAdAsset.TITLE,
                RequestParameters.NativeAdAsset.TEXT,
                RequestParameters.NativeAdAsset.CALL_TO_ACTION_TEXT,
                RequestParameters.NativeAdAsset.MAIN_IMAGE,
                RequestParameters.NativeAdAsset.ICON_IMAGE,
                RequestParameters.NativeAdAsset.STAR_RATING
     );
        
     RequestParameters mRequestParameters = new RequestParameters.Builder()
         .location(exampleLocation)
         .keywords(exampleKeywords)
         .desiredAssets(desiredAssets)
         .build();
    
  6. Call MoPubNative.makeRequest() to request an ad from the server:

     moPubNative.makeRequest(mRequestParameters);
    
  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() {
             @Override
             public void onNativeLoad(final NativeAd nativeAd) {
             }
             @Override
             public void onNativeFail(NativeErrorCode errorCode) {
             }
         };
    

    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() {
             @Override
             public void onImpression(View view) {
                 // Impress is recorded - do what is needed AFTER the ad is visibly shown here.
             }
    
             @Override
             public void onClick(View view) {
             }
         };
    

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.
    
  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.

     // 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).
     nativeAd.setMoPubNativeEventListener(moPubNativeEventListener);
     // Add the ad view to our view hierarchy
     parentView.addView(v);
    

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).

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

    For example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
    
     @Override
     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.

    For example (subclassing ArrayAdapter):

     int originalViewTypeCount = 2; // number of unique view types in the feed
    
     @Override
     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.

    For example (subclassing ArrayAdapter):

     mAdapterHelper = new AdapterHelper(context, start, interval);
    
     @Override
     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.

    For 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;
    
     @Override
     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.

    For example (subclassing ArrayAdapter):

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

Best Practice: Avoid Excessive Ad Requests

Making requests for ads that are never displayed to the user consumes 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 May 22, 2020

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.)