跳至主要內容

原生广告

大约 8 分钟

原生广告

概述

原生广告是一种与应用内容和设计自然融合的广告形式,开发者只需按照标准集成步骤即可在应用中无缝展示广告内容。原生广告能够与应用的界面和用户体验协调一致,不会干扰用户的正常使用。用户可以在浏览应用内容时自然地接触到这些广告,从而提高广告的接受度和互动性。开发者可以根据应用的风格和用户的需求定制广告的展示方式,以实现最佳的广告效果和用户体验。

模版渲染广告和开发者自渲染广告,统一使用 SAFeedAdManager 加载

SAFeedAdManager 方法介绍

方法说明
构造方法,传入广告位ID。
设置原生广告中的视频是否静音
设置所在的activity
设置期望的宽高,单位dp,当高度传0时,原生模版渲染广告会根据平台模版和宽度自适应调整高度
设置加载结果回调监听,在
之前设置
加载广告
获取本次瀑布流加载过程中失败的代码位信息

SAFeedAdManager.LoadListener 方法介绍

方法说明
加载成功
加载失败

SAFeedAd 方法介绍

属性说明
是否是原生模版渲染广告
获取模版渲染广告对象
获取开发者自渲染广告数据对象

模版渲染

由广告网络提供多种的广告模板样式,上下图文、左右图文、三小图+文等

场景常见于应用的内容信息流中与应用内容穿插展示,如资讯列表页每隔几条资讯穿插一条广告。

SANativeExpressAd 方法介绍

方法说明
设置模版渲染广告回调事件监听,在调用render前设置
渲染广告视图,在收到方法回调后,可以获取广告视图
获取广告视图,在收到方法回调后调用
销毁广告
对于已经加载成功,但未及时展示的广告,在展示前用此方法判断广告是否还可用
获取价格,单位为 分
获取本次广告填充的代码位信息

SAExpressFeedAd.InteractionListener 方法说明

方法说明
void sa_feedAdRenderSuccess()广告渲染成功
void sa_feedAdRenderFailure(AdError error)广告渲染失败
void sa_feedAdShowFail(AdError error)广告展示失败
void sa_feedAdDidShow()广告已经展示
void sa_feedAdDidClick()广告点击
void sa_feedAdDidExposure()广告曝光
void sa_feedAdDidClose()广告点击关闭

开发者自渲染

当广告网络提供的原生模版渲染广告的样式和展示场景无法满足需求时,可以采用原生开发者自渲染广告

使用自渲染的API,可以为应用打造自定义的样式和展示场景。

SANativeAdData 方法说明

方法说明
String getTitle()广告标题
String getDescription()广告文字内容
Bitmap getAdLogo()获取广告平台logo bitmap
String getAdLogoUrl()获取广告平台logo url
String getIconUrl()获取icon url
List<String>getImageList()获取图片url列表
SANativeADMediaMode getFeedAdMode()获取广告媒体素材类型,一图、多图、视频等形式
String getEcpm()获取价格,单位为分
boolean isDownAPPAd()是否是下载类广告
SADownAppInfo getDownAppInfo()下载应用的信息六要素
SAAdSourceInfo getFillAdSourceInfo()获取填充广告源信息

SADownAppInfo 下载类六要素方法说明

方法说明
String getAppName()应用名称
String getAuthorName()开发者名称
String getPrivacyUrl()隐私协议链接
String getAppVersionName()应用版本
String getAppPermissionUrl()权限说明链接
String getAppFunctionUrl()功能介绍链接

SANativeADMediaMode 媒体素材类型枚举说明

枚举说明
OneImage单张图片
GroupImage多张图片
Video视频类型
OnlyIcon只有一个appIcon类型

展示广告

要展示开发者原生自渲染广告,开发者需要自定义广告布局,从SANativeAdData中获取广告内容填充的布局中,并将布局元素传入到bindAdToView(ViewGroup adContainer, ImageView icon, ImageView adLogo, List<View> clickViews, List<View> ctaViews, View disLike, ViewGroup mediaContainer, List<ImageView> imgViews, SAUnifiedFeedAdInteractionListener listener)中:

参数说明是否必选
ViewGroup adContainer广告容器必填,如果传入无效值,广告将不能正常曝光,开发者不会获得收益
ImageView iconapp icon的imageView可选
ImageView adLogo广告网络logo视图可选
List<View> clickViews可响应点击的视图数组必填
List<View> ctaViewscta视图数组可选
View disLike关闭事件视图可选
ViewGroup mediaContainer用于展示视频的容器当广告素材类型为视频时,即getFeedAdMode()为SANativeADMediaMode.Video,必填
List<ImageView> imgViews用于展示广告图片素材的视图数组可选
SAUnifiedFeedAdInteractionListener listener广告生命周期事件回调可选

请求模版渲染广告示例

private void loadAd() {
    feedAdManager = new SAFeedAdManager("posid");
    feedAdManager.setActivity(this);
    feedAdManager.setMuted(true);
    feedAdManager.setAdSize(new SAAdSize(width, Height));

    feedAdManager.setLoadListener(new SAFeedAdManager.LoadListener() {
        @Override
        public void onFeedAdLoad(List<SAFeedAd> ads) {
            if (list != null && list.size() > 0) {
                SAFeedAd feedAd = list.get(0);
                if (feedAd.isExpress()) {
                        //模板渲染
                        SAExpressFeedAd expressFeedAd = feedAd.getExpressFeedAd();
                        expressFeedAd.setInteractionListener(new SAExpressFeedAd.InteractionListener() {
                            @Override
                            public void sa_feedAdRenderSuccess() {
                                View adView = expressFeedAd.getAdView();
                                adContainer.removeAllViews();
                            	adContainer.addView(view);
                            }
    
                            @Override
                            public void sa_feedAdRenderFailure(AdError adError) {}
    
                            @Override
                            public void sa_feedAdShowFail(AdError adError) {}
    
                            @Override
                            public void sa_feedAdDidShow() {}
    
                            @Override
                            public void sa_feedAdDidClick() {}
    
                            @Override
                            public void sa_feedAdDidExposure() {}
    
                            @Override
                            public void sa_feedAdDidClose() {
                                // 关闭事件,需要移除广告视图
        						adContainer.removeAllViews();
                            }
                        });
                        feedAd.getExpressFeedAd().isReady();
                        feedAd.getExpressFeedAd().render();
                    }else {
                    //自渲染参考下面示例代码
                }
        	}
        }

        @Override
        public void onError(AdError error) {
            
        }
    });

    feedAdManager.loadFeedAd();
}

请求开发者自渲染广告示例

public class MixFeedActivity extends Activity {
    private SAFeedAdManager feedAdManager;
    private List<SAFeedAd> feedAds = new ArrayList<>();
    private LoadMoreListView listView;
    private FeedListAdapter mFeedListAdapter;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_mix_feed);
        listView = findViewById(R.id.feed_list);
        listView.setLoadMoreListener(() -> {
            loadAd();
        });
        mFeedListAdapter = new FeedListAdapter(this, feedAds);
        listView.setAdapter(mFeedListAdapter);

        loadAd();
    }
    private void loadAd() {
        feedAdManager = new SAFeedAdManager("id");
        feedAdManager.setActivity(this);
        feedAdManager.setMuted(true);
        DisplayMetrics metrics = getResources().getDisplayMetrics();
        float scale =  metrics.density;
        int width = (int) (metrics.widthPixels / (scale <= 0 ? 1 : scale) + 0.5f);
        feedAdManager.setAdSize(new SAAdSize(width, 0));

        feedAdManager.setLoadListener(new SAFeedAdManager.LoadListener() {
            @Override
            public void onFeedAdLoad(List<SAFeedAd> ads) {
                // 广告请求成功
                if (listView != null) {
                    listView.setLoadingFinish();
                }
                if (ads == null || ads.isEmpty()) {
                    // 广告数据为空
                    return;
                }
                int loadCount = 15;// 模拟每次展示的Item刷新个数
                for (int i = 0; i < loadCount; i++) {
                    feedAds.add(null);
                }
                int totalCount = feedAds.size();
                Set<Integer> set = new HashSet<>();

                for (SAFeedAd feedAd : ads) {
                    if (feedAd == null) {
                        continue;
                    }
                    int random = (int) (Math.random() * loadCount) + totalCount - loadCount;
                    while (set.contains(random)) {
                        random = (int) (Math.random() * loadCount) + totalCount - loadCount;
                    }

                    set.add(random);
                    feedAds.set(random, feedAd);

                    setFeedAdInteractionListener(feedAd);
                }
                mFeedListAdapter.notifyDataSetChanged();
            }

            @Override
            public void onError(AdError error) {
                if (listView != null) {
                    listView.setLoadingError();
                }
                // 广告请求失败
            }
        });

        feedAdManager.loadFeedAd();
    }


    private void setFeedAdInteractionListener(SAFeedAd mixFeedAd) {
        //模板渲染
        if (mixFeedAd.isExpress()) {
            SAExpressFeedAd feedAd = mixFeedAd.getExpressFeedAd();
            feedAd.setInteractionListener(new SAExpressFeedAd.InteractionListener() {
                @Override
                public void sa_feedAdRenderSuccess() {
                // 渲染成功
                }

                @Override
                public void sa_feedAdRenderFailure(AdError error) {
                // 渲染失败
                }

                @Override
                public void sa_feedAdShowFail(AdError error) {
                // 展示失败
                }

                @Override
                public void sa_feedAdDidShow() {
                // 展示
                }

                @Override
                public void sa_feedAdDidClick() {
                // 点击
                }

                @Override
                public void sa_feedAdDidExposure() {
                // 曝光
                }

                @Override
                public void sa_feedAdDidClose() {
                // 点击关闭
                }
            });

            feedAd.render();
        } else {
            //自渲染
        }
    }

    private static class FeedListAdapter extends BaseAdapter {
        private Context mContext;
        private List<SAFeedAd> mFeedList;

        FeedListAdapter(Context context, List<SAFeedAd> feedList) {
            this.mContext = context;
            this.mFeedList = feedList;
        }

        @Override
        public int getCount() {
            return mFeedList.size();
        }

        @Override
        public SAFeedAd getItem(int position) {
            return mFeedList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public int getItemViewType(int position) {
            SAFeedAd feedAd = getItem(position);
            if (feedAd != null) {
                if (feedAd.isExpress()) {
                    return ItemViewType.ITEM_VIEW_TYPE_AD;
                } else {
                    switch (feedAd.getNativeAdData().getFeedAdMode()) {
                        case GroupImage:
                            return ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_GROUP;
                        case Video:
                            return ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_VIDEO;
                        default:
                            return ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_IMAGE;
                    }
                }

            } else {
                return ItemViewType.ITEM_VIEW_TYPE_NORMAL;
            }
        }

        @Override
        public int getViewTypeCount() {
            return 5;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            SAFeedAd feedAd = getItem(position);
            switch (getItemViewType(position)) {
                case ItemViewType.ITEM_VIEW_TYPE_AD:
                    return getExpressAdItemView(convertView, parent, feedAd.getExpressFeedAd());
                case ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_IMAGE:
                    return getImageItemView(convertView, parent, feedAd.getNativeAdData());
                case ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_VIDEO:
                    return getVideoItemView(convertView, parent, feedAd.getNativeAdData());
                case ItemViewType.ITEM_VIEW_TYPE_AD_NATIVE_GROUP:
                    return getGroupItemView(convertView, parent, feedAd.getNativeAdData());
                default:
                    return getNormalItemView(convertView, parent, position);
            }
        }

        private View getExpressAdItemView(View convertView, ViewGroup parent, final SAExpressFeedAd feedAd) {
            ExpressFeedAdViewHolder adViewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.feed_list_item_ad_container,
                        parent, false);
                adViewHolder = new ExpressFeedAdViewHolder(convertView);
                convertView.setTag(adViewHolder);
            } else {
                adViewHolder = (ExpressFeedAdViewHolder) convertView.getTag();
            }

            View adView = feedAd.getAdView();
            if (adView != null && adView.getParent() == null) {
                adViewHolder.mAdContainer.removeAllViews();
                adViewHolder.mAdContainer.addView(adView);
            }
            return convertView;
        }

        private View getImageItemView(View convertView, ViewGroup parent, final SANativeAdData feedAd) {
            NativeFeedAdImageViewHolder adViewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.self_feed_list_item_ad_container_01, parent, false);
                adViewHolder = new NativeFeedAdImageViewHolder(convertView);
                convertView.setTag(adViewHolder);
            } else {
                adViewHolder = (NativeFeedAdImageViewHolder) convertView.getTag();
            }
            List<View> clicks = new ArrayList<>();
            List<ImageView> imageViews=new ArrayList<>();
            FrameLayout container = adViewHolder.mAdContainer;
            ImageView logo = adViewHolder.iv_logo;
            ImageView bigImage = adViewHolder.imageView;
            clicks.add(bigImage);
            clicks.add(adViewHolder.tvTitle);
            clicks.add(adViewHolder.tvDes);
            clicks.add(logo);
            imageViews.add(bigImage);
            feedAd.bindAdToView(container, null, logo, clicks, null, null, null, imageViews, new SAUnifiedFeedAdInteractionListener() {
                @Override
                public void onAdShow() {
                    // 展示
                }

                @Override
                public void onAdClick() {
                    // 点击
                }

                @Override
                public void onAdError(int errorCode, String msg) {
                    // 展示失败
                }
            });
            if ("".equals(feedAd.getDescription())) adViewHolder.tvDes.setVisibility(View.GONE);
            else adViewHolder.tvDes.setVisibility(View.VISIBLE);
            adViewHolder.tvTitle.setText(feedAd.getTitle());
            adViewHolder.tvDes.setText(feedAd.getDescription());
            return convertView;
        }

        private View getGroupItemView(View convertView, ViewGroup parent, final SANativeAdData feedAd) {
            NativeFeedAdGroupImageViewHolder adViewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.self_feed_list_item_ad_container_03, parent, false);
                adViewHolder = new NativeFeedAdGroupImageViewHolder(convertView);
                convertView.setTag(adViewHolder);
            } else {
                adViewHolder = (NativeFeedAdGroupImageViewHolder) convertView.getTag();
            }
            adViewHolder.tvTitle.setText(feedAd.getTitle());
            adViewHolder.tvDes.setText(feedAd.getDescription());
            List<View> clicks = new ArrayList<>();
            List<ImageView> imageViews=new ArrayList<>();
            clicks.add(convertView);
            imageViews.add(adViewHolder.iv_1);
            imageViews.add(adViewHolder.iv_2);
            imageViews.add(adViewHolder.iv_3);
            clicks.addAll(imageViews);
            clicks.add(adViewHolder.iv_logo);
            clicks.add(adViewHolder.tvTitle);
            clicks.add(adViewHolder.tvDes);

            feedAd.bindAdToView(adViewHolder.mAdContainer, null, adViewHolder.iv_logo, clicks, null, null, null, imageViews, new SAUnifiedFeedAdInteractionListener() {
                @Override
                public void onAdShow() {
                    // 展示
                }

                @Override
                public void onAdClick() {
                    // 点击
                }

                @Override
                public void onAdError(int errorCode, String msg) {
                    // 展示失败
                }
            });
            return convertView;
        }

        private View getVideoItemView(View convertView, ViewGroup parent, final SANativeAdData feedAd) {
            NativeFeedAdVideoViewHolder adViewHolder;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.self_feed_list_item_ad_container_02, parent, false);
                adViewHolder = new NativeFeedAdVideoViewHolder(convertView);
                convertView.setTag(adViewHolder);
            } else {
                adViewHolder = (NativeFeedAdVideoViewHolder) convertView.getTag();
            }
            List<View> clicks = new ArrayList<>();
            List<ImageView> imageViews=new ArrayList<>();
            FrameLayout container = adViewHolder.mAdContainer;
            ImageView logo = adViewHolder.iv_logo;
            FrameLayout mediaContainer = adViewHolder.mediaContainer;
            clicks.add(container);
            clicks.add(mediaContainer);
            clicks.add(logo);
            feedAd.bindAdToView(container, null, logo, clicks, null, null, mediaContainer, imageViews, new SAUnifiedFeedAdInteractionListener() {
                @Override
                public void onAdShow() {
                    // 展示
                }

                @Override
                public void onAdClick() {
                    // 点击/
                }

                @Override
                public void onAdError(int errorCode, String msg) {
                    // 展示失败
                }
            });
            adViewHolder.tvTitle.setText(feedAd.getTitle());
            adViewHolder.tvDes.setText(feedAd.getDescription());
            return convertView;
        }

        @SuppressLint("DefaultLocale")
        private View getNormalItemView(View convertView, ViewGroup parent, int position) {
            FeedListAdapter.NormalViewHolder normalViewHolder;
            if (convertView == null) {
                normalViewHolder = new FeedListAdapter.NormalViewHolder();
                convertView =
                        LayoutInflater.from(mContext).inflate(R.layout.native_item_normal, parent, false);
                normalViewHolder.textView = convertView.findViewById(R.id.tv);
                convertView.setTag(normalViewHolder);
            } else {
                normalViewHolder = (FeedListAdapter.NormalViewHolder) convertView.getTag();
            }
            normalViewHolder.textView.setText(String.format("ListView item %d", position));
            return convertView;
        }

        @interface ItemViewType {
            int ITEM_VIEW_TYPE_NORMAL = 0;
            int ITEM_VIEW_TYPE_AD = 1;
            int ITEM_VIEW_TYPE_AD_NATIVE_IMAGE = 2;
            int ITEM_VIEW_TYPE_AD_NATIVE_VIDEO = 3;
            int ITEM_VIEW_TYPE_AD_NATIVE_GROUP = 4;
        }

        private static class NormalViewHolder {
            TextView textView;
        }
    }
}

上次编辑于: