原生广告是创建与应用内容融于一体的广告形式,支持开发者自由定制界面。

原生广告需要通过NativeAdLoader类获取。
NativeAdLoader类提供了NativeAdLoader.Builder类,可用于设置广告位ID、设置自定义选项和构建NativeAdLoader对象。
示例代码如下所示:
- // "testy63txaom86"为专用的测试广告位ID。
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() {
- @Override
- public void onNativeAdLoaded(NativeAd nativeAd) {
- // 广告获取完成后调用
- ...
- }
- }).setAdListener(new AdListener() {
- @Override
- public void onAdFailed(int errorCode) {
- // 广告获取失败时调用
- ...
- }
- });
- NativeAdLoader nativeAdLoader = builder.build();
当获取广告成功后,SDK会调用NativeAd.NativeAdLoadedListener监听器的onNativeAdLoaded()方法返回NativeAd对象。
当获取广告失败后,SDK会调用AdListener监听器的onAdFailed()方法。
NativeAdLoader提供loadAd()和loadAds()两种方法获取广告。
AdParam是唯一的参数,代码如下所示:
- nativeAdLoader.loadAd(new AdParam.Builder().build());
调用loadAd()后,SDK将对添加的监听器方法进行一次成功或失败的回调。
loadAds()请求有两个参数,除AdParam外,还有请求加载的广告数量,最大为5。SDK返回的广告数量将会小于等于所请求的广告数量,并且广告皆不相同。
代码如下所示:
- nativeAdLoader.loadAds(new AdParam.Builder().build(), 5);
调用loadAds()后,监听器将会根据返回的广告个数进行多次回调。请求多个广告时,可以在回调代码中使用NativeAdLoader.isLoading()方法来判断广告是否已获取完成。代码如下所示:
- // "testy63txaom86"为专用的测试广告位ID。
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- NativeAdLoader nativeAdLoader = builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() {
- @Override
- public void onNativeAdLoaded(NativeAd nativeAd) {
- if (nativeAdLoader.isLoading()) {
- // nativeAdLoader仍在获取广告
- ...
- } else {
- // nativeAdLoader完成广告获取
- ...
- }
- }
- }).build();
- nativeAdLoader.loadAds(new AdParam.Builder().build(), 5);
获取到广告后在监听器的回调方法中展示原生广告,需要在每个广告视图的一角展示“为什么看到此广告”的图标,并且必须展示广告标识。
以下是展示原生广告的步骤:
需要自定义一个布局用于展示NativeAd中的素材。
对于使用RelativeLayout来展示素材视图的原生广告,其视图层次结构示例如下:
- <com.huawei.hms.ads.nativead.NativeView xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- ... >
- <RelativeLayout
- ... >
- <com.huawei.hms.ads.nativead.MediaView
- android:id="@+id/ad_media"
- ... />
- <RelativeLayout
- ... >
- <TextView
- android:id="@+id/ad_title"
- ... />
- // 其他素材
- ...
- </RelativeLayout>
- // 其他素材
- ...
- </RelativeLayout>
- </com.huawei.hms.ads.nativead.NativeView>
获取到NativeView对象后,需要注册和填充素材。
注册和填充标题、多媒体的示例代码如下:
- // ad_native为定义的原生广告布局XML文件名
- NativeView nativeView = (NativeView) getLayoutInflater().inflate(R.layout.ad_native, null);
- nativeView.setTitleView(nativeView.findViewById(R.id.ad_title));
- ((TextView) nativeView.getTitleView()).setText(nativeAd.getTitle());
- nativeView.setMediaView((MediaView) nativeView.findViewById(R.id.ad_media));
- nativeView.getMediaView().setMediaContent(nativeAd.getMediaContent());
依次设置其他要展示的广告素材。
MediaView用于展示多媒体素材。如果获取的广告含有视频素材,则视频会在MediaView内播放。否则MediaView会显示一个图片素材。
示例代码如下:
- nativeView.setNativeAd(nativeAd);
将NativeView添加到界面即可展示原生广告。示例代码如下:
- private void loadAd() {
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() {
- @Override
- public void onNativeAdLoaded(NativeAd nativeAd) {
- // TODO
- ...
- // 获取NativeView视图
- NativeView nativeView = (NativeView) getLayoutInflater().inflate(R.layout.ad_native, null);
- // 注册和填充原生广告素材视图
- initNativeAdView(nativeAd, nativeView);
- // 将NativeView添加到界面
- FrameLayout adFrameLayout = findViewById(R.id.frame_layout_ad);
- adFrameLayout.removeAllViews();
- adFrameLayout.addView(nativeView);
- // TODO
- ...
- }
- });
- ...
- }
- private void initNativeView(NativeAd nativeAd, NativeView nativeView) {
- // 注册和填充标题素材视图
- nativeView.setTitleView(nativeView.findViewById(R.id.ad_title));
- ((TextView) nativeView.getTitleView()).setText(nativeAd.getTitle());
- // 注册和填充多媒体素材视图
- nativeView.setMediaView((MediaView) nativeView.findViewById(R.id.ad_media));
- nativeView.getMediaView().setMediaContent(nativeAd.getMediaContent());
- // 注册和填充其他素材视图
- ...
- // 注册原生广告对象
- nativeView.setNativeAd(nativeAd);
- }
为原生广告添加事件监听器的示例代码如下:
- NativeAdLoader nativeAdLoader = builder.setAdListener(new AdListener() {
- @Override
- public void onAdClicked() {
- // TODO
- ...
- }
- ...
- }).build();
当原生广告不再展示时,应将其销毁。
- nativeAd.destroy();
原生广告除了包含图片、文字外,还可能会包含视频素材。HUAWEI Ads SDK还提供了以下两个类用于视频的配置和控制。
通过VideoConfiguration类,可以对原生视频进行相关配置。示例代码如下:
- // "testy63txaom86"为专用的测试广告位ID。
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- VideoConfiguration videoConfiguration = new VideoConfiguration.Builder()
- // 设置是否在静音状态下开始播放视频素材。其默认值为true。
- .setStartMuted(true)
- .build();
- NativeAdConfiguration adConfiguration = new NativeAdConfiguration.Builder()
- .setVideoConfiguration(videoConfiguration)
- .build();
- builder.setNativeAdOptions(adConfiguration);
VideoOperator类用于视频信息获取和视频控制。控制器实例需要通过调用NativeAd.getVideoOperator()方法获得。当广告中没有视频素材时,此方法也会返回VideoOperator对象。
- VideoOperator videoOperator = nativeAd.getVideoOperator();
VideoOperator提供hasVideo()方法判断广告中是否有视频素材。
通过实现VideoOperator.VideoLifecycleListener类可以监听视频播放过程中的事件。
- videoOperator.setVideoLifecycleListener(new VideoOperator.VideoLifecycleListener() {
- @Override
- public void onVideoEnd() {
- // TODO
- ...
- super.onVideoEnd();
- }
- });
为了方便开发者可以快速实现原生广告的展示,我们提供了一套原生广告模板,可以集成到应用中使用。
原生广告模板提供了两种尺寸,并且都会按比例缩放以适应其父视图的宽度,你也可以随意改变模板的布局或样式。
展示形式如下图所示:

布局XML文件内容如下:
- <com.huawei.hms.ads.nativead.NativeView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/native_small_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:layout_marginTop="10dp"
- android:background="#FFFFFF"
- android:orientation="vertical">
- <RelativeLayout
- android:id="@+id/background"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentTop="true"
- android:orientation="vertical">
- <com.huawei.hms.ads.nativead.MediaView
- android:id="@+id/ad_media"
- android:layout_width="75dp"
- android:layout_height="50dp"
- android:layout_marginStart="24dp"
- android:layout_marginTop="8dp"
- android:layout_marginBottom="8dp"
- android:background="#8BC34A" />
- <RelativeLayout
- android:id="@+id/center_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginStart="107dp"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="48dp"
- android:layout_marginBottom="8dp"
- android:background="#FFFFFF">
- <TextView
- android:id="@+id/ad_title"
- android:layout_width="match_parent"
- android:layout_height="34dp"
- android:layout_marginBottom="16dp"
- android:alpha="1"
- android:textColor="#000000"
- android:textSize="@dimen/hiad_text_13_sp" />
- <TextView
- android:id="@+id/ad_source"
- android:layout_width="wrap_content"
- android:layout_height="14dp"
- android:layout_marginTop="36dp"
- android:alpha="0.6"
- android:maxWidth="132dp"
- android:textColor="#666666"
- android:textSize="@dimen/hiad_text_9_sp" />
- <TextView
- android:id="@+id/ad_flag"
- android:layout_width="16dp"
- android:layout_height="14dp"
- android:layout_marginStart="8dp"
- android:layout_marginTop="36dp"
- android:layout_toEndOf="@+id/ad_source"
- android:background="@drawable/native_flag_rounded_corners_shape"
- android:gravity="center"
- android:text="@string/ad_flag"
- android:textColor="#FFFFFF"
- android:textSize="8sp"
- android:textStyle="bold" />
- <Button
- android:id="@+id/ad_call_to_action"
- android:layout_width="44dp"
- android:layout_height="@dimen/hiad_16_dp"
- android:layout_alignParentEnd="true"
- android:layout_marginTop="34dp"
- android:background="@drawable/native_button_rounded_corners_shape"
- android:textColor="#FFFFFF"
- android:textSize="6sp" />
- </RelativeLayout>
- </RelativeLayout>
- </com.huawei.hms.ads.nativead.NativeView>
展示形式如下图所示:

布局XML文件内容如下:
- <com.huawei.hms.ads.nativead.NativeView xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/native_video_view"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_centerInParent="true"
- android:background="#FFFFFF"
- android:orientation="vertical">
- <RelativeLayout
- android:id="@+id/background"
- android:layout_width="match_parent"
- android:layout_height="wrap_content">
- <com.huawei.hms.ads.nativead.MediaView
- android:id="@+id/ad_media"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- <RelativeLayout
- android:id="@+id/left_bottom_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/ad_media">
- <TextView
- android:id="@+id/ad_title"
- android:layout_width="180dp"
- android:layout_height="19dp"
- android:layout_marginStart="24dp"
- android:layout_marginTop="16dp"
- android:alpha="1"
- android:textColor="#000000"
- android:textSize="@dimen/hiad_text_13_sp" />
- <TextView
- android:id="@+id/ad_source"
- android:layout_width="wrap_content"
- android:layout_height="19dp"
- android:layout_below="@id/ad_title"
- android:layout_marginStart="24dp"
- android:layout_marginTop="2dp"
- android:layout_marginBottom="16dp"
- android:alpha="0.6"
- android:maxWidth="158dp"
- android:textColor="#666666"
- android:textSize="@dimen/hiad_text_12_sp" />
- <TextView
- android:id="@+id/ad_flag"
- android:layout_width="20dp"
- android:layout_height="14dp"
- android:layout_marginStart="8dp"
- android:layout_marginTop="40dp"
- android:layout_toEndOf="@+id/ad_source"
- android:background="@drawable/native_flag_rounded_corners_shape"
- android:gravity="center"
- android:text="@string/ad_flag"
- android:textColor="#FFFFFF"
- android:textSize="8sp"
- android:textStyle="bold" />
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/right_bottom_view"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_below="@id/ad_media"
- android:layout_alignParentEnd="true">
- <Button
- android:id="@+id/ad_call_to_action"
- android:layout_width="72dp"
- android:layout_height="26dp"
- android:layout_alignParentEnd="true"
- android:layout_marginTop="23dp"
- android:layout_marginEnd="52dp"
- android:layout_marginBottom="23dp"
- android:background="@drawable/native_button_rounded_corners_shape"
- android:textColor="#FFFFFF"
- android:textSize="10sp" />
- </RelativeLayout>
- </RelativeLayout>
- </com.huawei.hms.ads.nativead.NativeView>
其中drawable/native_flag_rounded_corners_shape.xml文件内容如下:
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="#CCCCCC" />
- <padding
- android:bottom="1dp"
- android:left="1dp"
- android:right="1dp"
- android:top="1dp" />
- <corners
- android:bottomLeftRadius="2dp"
- android:bottomRightRadius="2dp"
- android:topLeftRadius="2dp"
- android:topRightRadius="2dp" />
- </shape>
其中drawable/native_button_rounded_corners_shape.xml文件内容如下:
- <shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="#214EF3" />
- <padding
- android:bottom="1dp"
- android:left="1dp"
- android:right="1dp"
- android:top="1dp" />
- <corners
- android:bottomLeftRadius="20dp"
- android:bottomRightRadius="20dp"
- android:topLeftRadius="20dp"
- android:topRightRadius="20dp" />
- </shape>
通过NativeAdConfiguration对象可以实现对原生广告的自定义设置。示例代码如下:
- // "testy63txaom86"为专用的测试广告位ID。
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- NativeAdConfiguration adConfiguration = new NativeAdConfiguration.Builder()
- .setVideoConfiguration(videoConfiguration) // 设置视频选项
- .setRequestCustomDislikeThisAd(true) // 是否要自定义“不再显示该广告”
- .build();
- builder.setNativeAdOptions(adConfiguration);
了解详细方法,请参见API文档中的NativeAdConfiguration.Builder类。
通过“不再显示该广告”功能,用户可以自行关闭不感兴趣的广告。
样例如下所示:

图1.原生广告展示视图 图2.广告选项展示视图

图3.不显示该广告原因选项视图 图4.原生广告已关闭视图
如果不想展示“广告已关闭”的视图,可调用NativeAd类中的setDislikeAdListener()方法为原生广告对象设置关闭广告事件监听器,并在监听器中的onAdDisliked()方法中添加自定义实现。当广告关闭时,SDK会回调监听器中的onAdDisliked()方法。
示例代码如下:
- NativeAdLoader.Builder builder = new NativeAdLoader.Builder(this, "testy63txaom86");
- builder.setNativeAdLoadedListener(new NativeAd.NativeAdLoadedListener() {
- @Override
- public void onNativeAdLoaded(NativeAd nativeAd) {
- ...
- nativeAd.setDislikeAdListener(new DislikeAdListener() {
- @Override
- public void onAdDisliked() {
- // TODO 广告关闭时调用
- }
- });
- }
- });
通过NativeAdConfiguration.Builder类中的setRequestCustomDislikeThisAd()方法可以设置是否要自定义“不再显示该广告”。当设置为自定义版“不再显示该广告”时,原生广告将会显示“为什么看到此广告”图标。如果需要隐藏“为什么看到此广告”图标,可调用NativeAdConfiguration.Builder类中的setChoicesPosition()方法将其设置为不可见。
示例代码如下:
- NativeAdConfiguration adConfiguration = new NativeAdConfiguration.Builder()
- .setRequestCustomDislikeThisAd(true) // 需要自定义“不再显示该广告”
- .setChoicesPosition(NativeAdConfiguration.ChoicesPosition.INVISIBLE) // 隐藏“为什么看到此广告”图标
- .build();
- NativeAdLoader nativeAdLoader = builder.setNativeAdOptions(adConfiguration).build();
当原生广告加载完成时,可调用NativeAd.isCustomDislikeThisAdEnabled()判断是否已设置为要自定义“不再显示该广告”。另外,可通过NativeAd.getDislikeAdReasons()方法获取“不再显示该广告”的信息列表,然后将其显示在开发者自定义界面中。
示例代码如下:
- if (nativeAd.isCustomDislikeThisAdEnabled()) {
- List<DislikeAdReason> dislikeAdReasons = nativeAd.getDislikeAdReasons();
- }
通过NativeAd.dislikeAd()方法可以将被选中的“不再显示该广告”选项信息反馈给SDK。
示例代码如下:
- nativeAd.dislikeAd(dislikeAdReason);
原生广告测试广告位ID,仅可用于调测原生广告功能,不可用于广告变现,在应用正式发布前需替换为正式的原生广告位ID,开发者应在应用发布前申请真实的广告位ID并替换测试广告位ID。
原生广告测试广告位ID列表如下:
广告形式 | 展示形式 | 尺寸 | 比例 | 测试广告位ID |
原生广告 | 大图文 | 1080*607 | 16:9 | testu7m3hc4gvm |
原生广告 | 小图文 | 225*150 | 3:2 | testb65czjivt9 |
原生广告 | 视频文 | 640*360 | 16:9 | testy63txaom86 |
具体实现可以参考示例代码,运行示例代码可以看到如下效果图:
