2.3.Ads Format
Mediation currently supports 5 types of advertisements, including banner advertisement, interstitial advertisement, native advertisement, splash advertisement, and rewarded video. The methods are different, please refer to the following description of the access method of each advertisement form.
- All advertising operations should be executed on the main thread
- Multiple processes cannot initialize the SDK at the same time
- All Ads should be loadedAd() at one time and show() at one time, so as to ensure that each time you get the best advertisement, do not loadAd() at one time and show() multiple times
- Avoid multiple loadAd() on the same object, because multiple loadAd() on the same object will overwrite the last requested ad.
2.3.1 Banner Ads
Introduction
Images at the top, middle or bottom of the app. Supported ad sizes: 20:3, 3:2, the renderings are as follows:
20:3 | 3:2 |
---|---|
![]() ![]() | ![]() |
Access steps
1. Add TBannerView
First, add TBannerView to the page where you want to display the banner advertisement, you can add it in the corresponding xml file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#e8e8e8"
android:orientation="vertical">
<com.hisavana.mediation.ad.TBannerView
android:id="@+id/bannerview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true" />
</RelativeLayout>
2.3.1.2 Initialize the ad object
//banner_1 is slot id
adview.setAdSize(BannerSize.SIZE_320x50);
adview.setAdUnitId("banner_1");
2.3.1.3 Build an ad request
TAdRequestBody tAdRequest = new TAdRequestBody.AdRequestBodyBuild()
.setAdListener(new TAdAlliance(this))
.build();
adview.setRequestBody(tAdRequest);
2.3.1.4 Start requesting ads
The loadAd() method requesting an advertisement will call back to the client if the optimal advertisement is returned within the set waiting time.
adview.loadAd();
2.3.1.5 Advertising Events
The callbacks for monitoring advertisement requests, filling, displaying, and clicking are as follows:
private static class TAdAlliance extends TAdListener {
@Override
public void onLoad() {
// Request success
}
@Override
public void onError(TAdErrorCode errorCode) {
// Request failed
}
@Override
public void onShow() {
// Called when an ad is displayed
}
@Override
public void onClicked() {
// Called when an ad is clicked
}
@Override
public void onClosed() {
//Added in sdk2.1.0.0+ version, the ad can be closed after the close is triggered
if(adview != null && adview == bannerView){
adview.destroy();
adview.removeAllViews();
}
}
@Override public void onShowError(TAdErrorCode errorCode) {
//Callback when ad display fails, new in sdk2.6.0.1+
}
}
- In sdk2.1.0.5+, onLoad(), onShow(), onClicked(), onClosed() methods are changed to onLoad(int source), onShow(int source), onClicked(int source), onClosed(int source).
- source indicates the advertising source, and the values are as follows: Ssp=0; Admob=1; fan=2; Applovin=3; Unity=4; Iron_source=5; Pangle=6; Inmobi=8; Vungle=12; Adcolony=11; For example: if the ad filling shows a pangle ad, then source=6.
2.3.1.6 Destroy Ads
When the ad is displayed, the ad will be destroyed after exiting the interface.
@Override
protected void onDestroy() {
super.onDestroy();
if (adview != null) {
adview.destroy();
adview.removeAllViews();
adview = null;
}
}
TBannerView
TBannerView is the placeholder view of the banner advertisement, the length and width need to be at least larger than the size of TAdBannerSize, otherwise there will be an error in the display of the advertisement
When using the adaptivebanner of admob, the Banner Size needs to use 320 * 50
Banner Size
Size dp (单位: dp) | BannerSize constant |
---|---|
320*50 | SIZE_320x50 |
320*90 | SIZE_320x90 |
320*100 | SIZE_320x100 |
320*250 | SIZE_320x250 |
2.3.1.7 Other APIs
adview.resume();
adview.pause();
Note: When adding a Mintergral ad source, when the system's onResume and onPause are called, the media needs to actively call the above two life cycle callback methods, which will reduce the number of errors in the Mintergral ad source.
2.3.2 Interstitial Ads
Introduction
The ad format that appears when a user opens or switches to your app. The supported ad sizes are 1:1, 9:16, and 3:2. The renderings are as follows:
1:1 | 9:16 | 3:2 |
---|---|---|
![]() | ![]() | ![]() |
Access steps
2.3.2.1 Initialize the ad object
mTInterstitialAd = new TInterstitialAd(this, "interstitial_1");
2.3.2.2 Build the request body
TAdRequestBody tAdRequest = new TAdRequestBody.AdRequestBodyBuild()
.setAdListener(new TAdAlliance(this))
.build();
mTInterstitialAd.setRequestBody(tAdRequest);
2.3.2.3 Request Ads
mTInterstitialAd.loadAd();
2.3.2.4 Preload Ads
mTInterstitialAd.preload();
illustrate:
- If an advertisement is requested in advance before entering the advertisement scene, please call the preload interface.
- To request an advertisement in real time when entering an advertisement scene, please call the load interface.
- The two cannot be used together. If used incorrectly, the pre-triggered fill rate and the triggered trigger presentation rate will be abnormal, which will seriously affect media revenue.
- Applicable to sdk version 1.2.1.0+, this method is only used to trigger a cached ad request, and will not call back Step 2: The listening event of the AdListener passed in when the request body is constructed. The sdk version 1.3.0.0+ adds a callback method. When the callback is successfully filled, the media can call the show() method to display the advertisement directly.
2.3.2.5 Display Ads
if (mTInterstitialAd != null && mTInterstitialAd.isReady()) {
mTInterstitialAd.show();
}
2.3.2.6 Destroy Ads
if (mTInterstitialAd != null) {
mTInterstitialAd.destroy();
mTInterstitialAd = null;
}
2.3.2.7 Other APIs
mTInterstitialAd.isReady()
Description: Added API in skd1.3.0+ to judge whether the advertisement is valid or not, and use it before displaying the advertisement.
2.3.3 Native ads
Introduction
Information flow, including large and small images, text and buttons. Divided into self-rendering and template rendering.
Self-rendering: The actual presentation style is determined by the media. Display Native ads in your Apk, when you use Native API to access ads, you will create the following native ads.


Access steps
2.3.3.1 Add TAdNativeView
First add TAdNativeView to the layout file where you want to display native ads
<com.hisavana.mediation.ad.TAdNativeView
android:id="@+id/native_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/load_content" />
2.3.3.2 Create a new layout file
Create a new layout file native_install.xml of the native advertising element, in which the icon in the advertising element is rendered with TIconView, and the large image is rendered with TMediaView, as follows:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ad_unit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/item_background"
tools:ignore="MissingDefaultResource">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal"
android:paddingTop="10dp"
android:paddingBottom="10dp">
<com.hisavana.mediation.ad.TIconView
android:id="@+id/native_ad_icon"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="5dp"
android:paddingRight="16dp">
<TextView
android:id="@+id/native_ad_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:ellipsize="end"
android:lines="1"
android:text="Title"
android:textColor="@android:color/black"
android:textSize="18sp" />
<TextView
android:id="@+id/native_ad_body"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text="des1"
android:textColor="@android:color/black"
android:textSize="15sp" />
<!-- des2 -->
<TextView
android:id="@+id/des2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="2"
android:text=""
android:textColor="@android:color/black"
android:textSize="15sp" />
<RatingBar
android:id="@+id/rating"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:isIndicator="false"
android:numStars="5"
android:stepSize="0.5"/>
</LinearLayout>
</LinearLayout>
<com.hisavana.mediation.ad.TMediaView
android:id="@+id/coverview"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/call_to_action"
android:paddingVertical="10dp"
android:layout_marginHorizontal="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="DOWNLOAD NOW!"
android:gravity="center"
android:textAllCaps="false" />
</LinearLayout>
<!-- Advertising AdChoicesView -->
<com.hisavana.mediation.ad.TAdChoicesView
android:id="@+id/adChoicesView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="150dp"
android:layout_marginTop="100dp" />
<com.hisavana.mediation.ad.TAdCloseView
android:id="@+id/adCloseView"
android:layout_toLeftOf="@+id/adChoicesView"
android:layout_width="12dp"
android:layout_height="12dp"/>
<com.hisavana.mediation.ad.TStoreMarkView
android:id="@+id/store_mark_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
</RelativeLayout>
2.3.3.3 Initialize the ad object
tNativeAd = new TNativeAd(this, "native_1");
2.3.3.4 Start requesting ads
When requesting an advertisement, it will call back the onLoad(List<TAdNativeInfo> tAdNativeInfos)
method of the advertisement monitor and return the optimal advertisement, as follows:
TAdRequestBody requestBody = new TAdRequestBody.AdRequestBodyBuild()
.setAdListener(new TAdAlliance(this))
.build();
tNativeAd.setRequestBody(requestBody);
tNativeAd.loadAd()
@Override
public void onLoad(List<TAdNativeInfo> tAdNativeInfos) {
super.onLoad();
inflateView(tAdNativeInfos.get(0));
}
Note: The main image and title of the ad are required, and others (such as the ad icon, ad description, etc.) are optional, and the media needs to adjust the layout according to whether the optional item has a return value TAdNativeInfo
- In sdk2.1.0.5+, the methods of
onLoad(List tAdNativeInfos)
,onShow()
,onClicked()
,onClosed()
are changed toonLoad(List tAdNativeInfos, int source)
,onShow (int source)
,onClicked(int source)
,onClosed(int source)
. - source indicates the advertising source, and the values are as follows:
Ssp=0; Admob=1; fan=2; Applovin=3; Unity=4; Iron_source=5; Inmobi=8; Vungle=12; Adcolony=11; Pangle=6
; For example: this ad filling displays a pangle ad, then source = 6.
2.3.3.5 Preload Ads
tNativeAd.preload();
illustrate:
- If an advertisement is requested in advance before entering the advertisement scene, please call the preload interface.
- To request an advertisement in real time when entering an advertisement scene, please call the load interface.
- The two cannot be used together. If used incorrectly, the pre-triggered fill rate and the triggered trigger presentation rate will be abnormal, which will seriously affect media revenue.
- Applicable to sdk version 1.2.1.0+, this method is only used to trigger a cached ad request, and will not call back Step 4: The listening event of the AdListener passed in when constructing the request body.
- The sdk version 1.3.0.0+ adds a callback method. When the callback is successfully filled, the media can call the bindNativeView() method to display the advertisement directly.
- For sdk version 1.4.2.4+, considering the preloading scenarios of some native advertisements, there is no need to add advertisements, and the media can achieve the purpose by not setting AdListener in the preloading phase.
2.3.3.6 Rendering ads
After the ad request is successful, the ad will be rendered. It is recommended to display the ad when there is a network.
- When the ad slot is an icon type, it is not necessary to set the main image, but only need to set the icon.
- If the connected SDK version is 2.2.0.0+, you need to add storeMarkView (app store logo), otherwise it will affect the jump link for downloading advertisements
...
@Override
public void onLoad(List<TAdNativeInfo> tAdNativeInfos) {
inflateView(tAdNativeInfos.get(0))
}
private void inflateView(TAdNativeInfo adNativeInfo) {
if(adNativeInfo == null) return;
if (mNativeInfo != null) {
mNativeInfo.release();
}
mNativeInfo = adNativeInfo;
ViewBinder viewBinder = new ViewBinder.Builder(R.layout.native_install)
.titleId(R.id.native_ad_title)
.iconId(R.id.native_ad_icon)
.callToActionId(R.id.call_to_action)
.descriptionId(R.id.native_ad_body)
.mediaId(R.id.coverview)
.adChoicesView(R.id.adChoicesView) //Advertising AdChoicesView
.adCloseView(R.id.adCloseView)
.storeMarkView(R.id.store_mark_view)//sdk2.2.0.1 added API, storeMarkView is the app store identifier
.contextMode(NativeContextMode.NORMAL)
.iconDrawable(iconDrawable) //Change icon content SDK version 2.3.2 support
.build();
tNativeAd.bindNativeView(nativeView, adNativeInfo, viewBinder);
}
2.3.3.7 Close ad
@Override
public void onClosed() {
//This method will not be called back in native ads
}
@Override
public void onClosed(TAdNativeInfo tAdNativeInfo) {
//Added in sdk2.1.0.1+ version, callback when clicking the close button of the advertisement, you can choose to call destroyShow() in the callback
// to destroy the ad. If it is used in the list, the position of the current advertisement in the list can be determined according to taNativeInfo, and it can be deleted dynamically
if(tAdNativeInfo == mNativeInfo){
destroyShow();
}
}
public void destroyShow() {
if(mNativeInfo != null) {
mNativeInfo.release();
}
if (nativeView != null) {
nativeView.release();
}
mNativeInfo = null;
nativeView = null;
}
2.3.3.8 Information flow advertisement display method
Pass in a View for reuse when building ViewBinder.Builder. as follows:
View itemView =
LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_ad_layout, viewGroup, false);
// bind view
ViewBinder viewBinder = new ViewBinder.Builder(itemView)
.titleId(R.id.native_ad_title)
.iconId(R.id.native_ad_icon)
.callToActionId(R.id.call_to_action)
.descriptionId(R.id.native_ad_body)
.mediaId(R.id.coverview)
.adChoicesView(R.id.adChoicesView) //Advertising AdChoicesView
.build();
tNativeAd.bindNativeView(nativeView, adNativeInfo, viewBinder);
2.3.3.9 Custom ad clickable elements
If you need to customize the ad click event, call the actionIds(Integer... actionIds)
method in ViewBinder
// actionIds
ViewBinder b = new ViewBinder.Builder(R.layout.native_install)
.titleId(R.id.native_ad_title) //Set the id of the title control
.iconId(R.id.native_ad_icon) //Set the id of the icon control
.callToActionId(R.id.call_to_action) //Set the ID of the button control
.descriptionId(R.id.native_ad_body) //Set the ID of the description control
.mediaId(R.id.coverview) //Set the ID of the advertising main image control
.actionIds(R.id.ad_action, R.id.coverview) //Click on the event to add
.ratingId(R.id.rating)//sdk1.2.1.8 support, control is RatingBar
.priceId(R.id.price) ///sdk1.2.1.8 support
.build();
related policy:
- Only the ad title, URL, call-to-action, and image assets are clickable (clickable "blank" areas are prohibited).
- The background of the ad must be unclickable. If an image element is used as the ad background, the image must not be clickable.
2.3.3.10 Destroy ads
When an advertisement is used up, it can be destroyed next time if it is no longer used. Call mNativeInfo.release()
.
@Override
protected void onDestroy() {
if (tNativeAd != null) {
tNativeAd.destroy();
tNativeAd = null;
}
if (mNativeInfo != null) {
mNativeInfo.release();
}
if (nativeView != null) {
nativeView.release();
}
layout = null;
mNativeInfo = null;
nativeView = null;
super.onDestroy();
}
2.3.3.11 Other APIs
Description: Added API in skd1.3.0+ to judge whether the advertisement is valid or not, and use it before displaying the advertisement.
adNativeInfo.isExpired()
2.3.4 Splash ad
Introduction
Ad styles that appear at natural endpoints and transitional segments support ad sizes of 9:16, 1:2, and 2:3. The effect is as follows:
9:16 | 1:2 | 2:3 |
---|---|---|
![]() | ![]() | ![]() |
Access steps
2.3.4.1 Add TSplashView
First add TSplashView to the layout file where you want to display the screen-opening ad as follows:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.hisavana.mediation.ad.TSplashView
android:id="@+id/splash_ad"
android:layout_width="match_parent"
android:layout_weight="1"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="@id/logo"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2.3.4.2 Initialize the open screen ad object
TSplashView tSplashView = findViewById(R.id.splash_ad);
TSplashAd tSplashAd = new TSplashAd(this, "splash_id");
2.3.4.3 Build the request body
tSplashAd.setRequestBody(
new TAdRequestBody.AdRequestBodyBuild()
.setAdListener(new TAdListener(this)).build());
2.3.4.4 Set skip monitoring
tSplashAd.setOnSkipListener(new TOnSkipListener());
private class TOnSkipListener implements OnSkipListener {
@Override
public void onClick() {
SplashAdActivity.this.finish();
ToastUtil.showLongToast("skip button click");
}
@Override
public void onTimeReach() {
ToastUtil.showLongToast("time reach");
}
}
Suggest:
Regarding the processing method of jumping to the home page after clicking the open-screen advertisement: the developer needs to record the click state isClicked = true
in the onClicked()
callback in the startup page, and do the jump to the main page in the onResume()
method, Remove the logic processing of the screen-opening view.
@Override
public void onClicked() {
isClicked = true;
}
@Override
protected void onResume() {
super.onResume();
if (isClicked){
} }
...
//Jump to Home
guideToMain();
//remove open screen view
if (tSplashView!= null && tSplashView.getParent() != null){
((ViewGroup) tSplashView.getParent()).removeView(tSplashView);
}
2.3.4.5 Request Ads
tSplashAd.loadAd();
2.3.4.6 Preload Ads
tSplashAd.preload();
illustrate:
- If an advertisement is requested in advance before entering the advertisement scene, please call the preload interface.
- To request an advertisement in real time when entering an advertisement scene, please call the load interface.
- The two cannot be used together. If used incorrectly, the pre-triggered fill rate and the triggered trigger presentation rate will be abnormal, which will seriously affect media revenue.
- Applicable to sdk version 1.2.1.0+, this method is only used to trigger a cached ad request, and will not call back Step 3: The listening event of the AdListener passed in when constructing the request body. The sdk version 1.3.0.0+ adds a callback method. When the callback is successfully filled, the media can call the show() method to display the advertisement directly.
2.3.4.7 Display Ads
tSplashAd.showAd(TSplashView);
The following APIs are added in sdk1.1.1.2 - sdk2.2.0.1 version, logoLayout is the layout of media incoming. Allows the media to pass in the logo and name. The bottom media logo information is rendered inside the sdk, and the bottom area is 25% of the height of the phone screen. The effect is as shown in the figure:
tSplashAd.showAd(TSplashView, logoLayout);

2.3.4.8 Close ad
@Override
public void onClosed() {
//Added in sdk2.1.0.0+ version, you can choose to call tSplashAd.destory() to close the advertisement after receiving the callback
if(tSplashAd != null){
tSplashAd.destroy();
tSplashAd = null;
}
}
2.3.4.9 Destroy ads
@Override
protected void onDestroy() {
super.onDestroy();
if(tSplashAd != null){
tSplashAd.destroy();
tSplashAd = null;
}
}
2.3.4.10 Other APIs
tSplashAd.isReady()
Description: Added API in skd1.3.0+ to judge whether the advertisement is valid or not, and use it before displaying the advertisement.
TSplashAd.hasCache("splash_id")
Description: Added API in skd1.3.0+, this API can get whether there are advertisements in the cache pool (running cache).
The media can pre-trigger during the use of the application to request the open-screen advertisement material. When it needs to be displayed, call this API to determine whether there is an advertisement in the buffer pool. If there is, call the trigger display interface; if not, Then call the trigger interface.
TSplashAd.getAdSource()
Description: Added an API in skd1.4.2+, this API can get the source of filling advertisements. Filling hisavana ad returns 0, filling admob ad returns 1, and returning -1 if no ad is currently obtained.
TSplashAd.resume();
TSplashAd.pause();
Note: When adding a Mintergral ad source, when the system's onResume and onPause are called, the media needs to actively call the above two life cycle callback methods, which will reduce the number of errors in the Mintergral ad source.
2.3.5 Rewarded Videos
Introduction
Rewarded videos are generally displayed on the game page of the app. Get the corresponding reward after playing the ad in full screen.
Access steps
2.3.5.1 Initialize the incentive video object
TVideoAd tVideoAd = new TVideoAd(this, "video_id");
2.3.5.2 Build the request body
TAdRequestBody tAdRequest = new TAdRequestBody.AdRequestBodyBuild() .setAdListener(new TAdAlliance(this)) .build();
tVideoAd.setRequestBody(tAdRequest);
2.3.5.3 Set up ad listener events
The callbacks for monitoring the filling, displaying, clicking, closing, and obtaining rewarded video rewards of advertisements are as follows:
private static class TAdAlliance extends TAdListener {
@Override public void onLoad() { super.onLoad();//Get success}
@Override public void onError(TAdErrorCode errorCode) { //Ad loading failed Reason for failure:errorCode.getErrorMessage() }
@Override public void onShow() { //Ad display }
@Override public void onClicked() { //Ad clicked }
@Override public void onClosed() { //Ad closed }
@Override public void onRewarded() { super.onRewarded(); //Get incentive rewards }
@Override public void onShowError(TAdErrorCode errorCode) { //Callback when ad display fails, new in sdk2.6.0.1+ }
}
-In sdk2.1.0.5+, 'onLoad (List tAdNativeInfos)', 'onShow()', 'onClicked()', 'onClosed()', method changed to 'onLoad (List tAdNativeInfos, int source)', 'onShow (int source)', 'onClicked (int source)', and 'onClosed (int source)'.
-Source represents the advertising source, with the following values: Ssp=0; Admob=1; fan=2; Applovin=3; Unity=4; Iron_ source=5; Inmobi=8; Vungle=12; Adcolony=11; Pangle=6
; For example, if this advertisement is filled with a single advertisement, then source=6.
2.3.5.4 Request Ads
tVideoAd.loadAd();
2.3.5.5 Preload Ads
tVideoAd.preload();
illustrate:
- If an advertisement is requested in advance before entering the advertisement scene, please call the preload interface.
- To request an advertisement in real time when entering an advertisement scene, please call the load interface.
- The two cannot be used together. If used incorrectly, the pre-triggered fill rate and the triggered trigger presentation rate will be abnormal, which will seriously affect media revenue.
- Applicable to sdk version 1.2.1.0+, this method is only used to trigger a cached ad request, and will not call back Step 2: The listening event of the AdListener passed in when the request body is constructed. The sdk version 1.3.0.0+ has added a callback method. When the callback is successfully filled, the media can call the show() method to display the advertisement directly
2.3.5.6 Display ads
if (tVideoAd != null && tVideoAd.isReady()) { tVideoAd.show(this); }
2.3.5.7 Destroy ads
@Override
protected void onDestroy() {
super.onDestroy();
if (null != tVideoAd) { tVideoAd.destroy(); }
}
Note: Incentive videos must add admob or facebook dependencies, otherwise it will cause an exception.
2.3.5.8 Other APIs
tVideoAd.isReady()
Description: Added API in skd1.3.0+ to judge whether the advertisement is valid or not, and use it before displaying the advertisement.