Native Ads

Quick Look - Example Integrations. For a better understanding please start with the information below.

Native ads are different from standard ad units in that rather than being a single, self contained entity from the perspective of a publisher, they are a collection of individual components that can be laid out and interacted with individually.

Due to their flexible nature and the various components that might be involved, the MM Ad SDK uses a concept of native ad type to provide a contract of sorts that a publisher is able to rely on. Each native type represents a collection of N number of individual components and guarantees the existence of specific components within the native ad response. This guarantee is important because some native types can have optional components that may or may not be present.

Components within a native ad each have a “type” that can almost be thought of as a data type like you would find in most programming languages. The type that is associated with a component indicates certain properties about the component such as:

  • role (icon image, main image, title text, etc)
  • content type (text, image, button, etc)
  • content restraints (max size of text string, etc)

Native type definitions are then just a collection of various components and rules about which are required to display and which are not. In order to record impressions, native ads are required to display certain elements tagged as “publisher required.” These are the components of the ad which are guaranteed display for advertisers. Other components may be present, but their display is considered optional. Where possible, you should choose to display optional elements to help drive user engagement. A list of all available native types and their associated components can be found here

The type for a native ad response can be retrieved by calling:

nativeAd.getNativeType()

The native type string can be used for determining which components to access or which layouts to pass to the SDK when trying to display native ad content.

Interaction with native ads within the MM Ad SDK can be broken up into two basic approaches - accessor model and layout model.

Accessor Model

With the accessor model, native ad content is used by accessing each component individually. For example, if a native ad response has title, icon and disclaimer components then the publisher would call a getter method for each of those components and layout those individual views themselves.

TextView title = nativeAd.getTitle();
ImageView icon = nativeAd.getIconImage();
TextView disclaimer = nativeAd.getDisclaimer();

The views that are returned already have click listeners associated with them so no wiring is needed beyond taking the view and inserting it into a layout for display.

One interesting thing with the accessor model is that the impression must be fired manually by the publisher by calling:

nativeAd.fireImpression();

Note that the SDK tracks accessed elements and will not fire the impression if all the required components for the native type have not been displayed.

A full working example of the accessor model can be found within the sample app packaged with the SDK (NativeActivity.java).

Layout Model

With the layout model, the layout of the individual native ad components is handled by the SDK. In the layout model, once a native ad response is received the publisher can ask the SDK to populate a specified layout with native ad content contained within the native ad response. In this approach, the click handling and impression firing is handled automatically by the SDK.

When the SDK is trying to populate a layout with native ad content, validation will occur that ensures the provided layout has placeholder views for the required components of the native type in question. A detailed breakdown of what required components, native types and component identifiers are provided here.

A native layout can be utilized once a native ad is successfully retrieved by calling either:

  • “inflateLayout” on the native ad instance and passing it an array of layout ids to try and load that map to layouts defined with the app resources
  • “updateLayout” on the native ad instance and passing it a concrete view that has child views with appropriate tags

Note that native layouts can be defined within XML or programmatically.

Individual assets are positioned within a layout by inserting placeholder views within the layout that are the appropriate view type and have a tag that identifies which asset the placeholder is meant for. For example, the following shows a placeholder view for the first instance of the icon image associated with a native ad:

<ImageView
  android:id="@+id/iconImage"
  android:layout_width="@dimen/native_icon_size"
  android:layout_height="@dimen/native_icon_size"
  android:layout_marginTop="@dimen/native_icon_top_margin"
  android:tag="iconImage_1"/>

When the SDK tries to insert the native ad icon into a specified layout, the SDK will look for a view with the tag “iconImage_1” that is also a ImageView. If a view with those requirements are found, the view will be updated appropriately with the native ad asset and associated click handling.

Tag identifiers take the form of “_” where the component ID is the string identifier for a specific native component defined as part of a specific native type and the component instance is the instance of the component within the native ad (starting with 1, not 0).

An example of using a native layout that has been defined in XML after a native ad has been loaded:

View nativeAdView = findViewById(R.id.native_ad);
nativeAdView = nativeAd.inflateLayout(NativeXMLActivity.this, new int[]{R.layout.native_ad});

The above snippet will ask the SDK to try and load the native ad content associated with the “nativeAd” object into the “native_ad” layout. If the SDK determines that there is not a valid layout in the list of layout provided, then null will be returned and an error is logged.

A full working example of the layout model can be found within the sample app packaged with the SDK (NativeXMLActivity.java).

 

Example Integration

NOTE: Items in source like <YOUR_PLACEMENT_ID> must be replaced with your information.

1. Create the native placement and set the listeners.
try {
  NativeAd nativeAd = NativeAd.createInstance(<YOUR_PLACEMENT_ID>, NativeAd.NATIVE_TYPE_INLINE);
  
  nativeAd.setListener(new NativeAd.NativeListener() {
	  @Override
	  public void onLoaded(NativeAd nativeAd) {
		 Log.i(TAG, "Native ad loaded");

		 try {
			View nativeAdView = nativeAd.inflateLayout(MainActivity.this, new int[]{R.layout.native_ad});

			// Verify you have received a populated layout
			if (nativeAdView != null) {
			   LinearLayout adContainer = (LinearLayout) findViewById(R.id.ad_container);

			   int adWidth = getResources().getDimensionPixelSize(R.dimen.native_ad_width);

			   // Attach the layout to your view hierarchy
			   LinearLayout.LayoutParams lp =
				  new LinearLayout.LayoutParams(adWidth, ViewGroup.LayoutParams.WRAP_CONTENT);

			   adContainer.addView(nativeAdView, lp);
			}

		 } catch (MMException e) {
			Log.e(TAG, "Native layout could not be inflated.", e);
		 }
	  }


	  @Override
	  public void onLoadFailed(NativeAd nativeAd, NativeAd.NativeErrorStatus errorStatus) {
		 Log.i(TAG, "Native ad loaded");
	  }


	  @Override
	  public void onClicked(NativeAd nativeAd, NativeAd.ComponentName componentName, int instanceId) {
		 Log.i(TAG, "Native ad loaded");
	  }


	  @Override
	  public void onAdLeftApplication(NativeAd nativeAd) {
		 Log.i(TAG, "Native ad loaded");
	  }


	  @Override
	  public void onExpired(NativeAd nativeAd) {
		 Log.i(TAG, "Native ad loaded");
	  }
	});
	
} catch (MMException e) {
  Log.e(TAG, "Error creating native ad", e);
}
2. Request the native ad.
try {
  nativeAd.load(context, null);
} catch (MMException e) {
  Log.i(TAG, "Unable to load native ad content, exception occurred");
  e.printStackTrace();
}

Additional Topics