信息流广告

简介

SDK为接入方提供了可自定义布局的信息流广告,包含大图、小图、组图和视频以及模板等五种基本样式类型(具体的布局摆放可自行定义),及电话拨打、应用下载、跳转到落地页、跳转到浏览器四种交互类型。

注意事项

①聚合SDK是通过广告位ID发起广告请求的,切记不要使用混淆。

②在广告接入前需要明确各ADN对应聚合SDK广告样式情况,以确保正确完成广告接入,避免由于广告类型不匹配导致接入报错等情况的发生。

③由于各广告平台对于包名校验规则不同,需确保在平台填写的包名符合各ADN平台规范,避免由于包名校验不匹配导致的无广告返回情况的产生。

④广告请求时机,建议在收到SDK初始化成功回调后发起广告请求,当SDK初始化回调一直失败时,建议首先明确应用ID及广告位ID是否赋值正确、是否有多余空格、是否是网络不稳定导致的超时等,当排查后无法定位问题时,建议通过抓包将config字段下的加密内容提供过来,我们协助定位。

⑤如若针对展示失败有重试机制,建议只重试一次即可,避免无限重试引发死循环场景。

⑥自渲染类型广告,在展示广告View时,广告元素如title,下载button等相关的控件,它们的父类必须使用NativeSelfRenderAdContainer布局 ,否则将会影响广告点击计费事件。视频类容器也需要使用必须使用NativeSelfRenderAdContainer布局,否则可能会影响展示或者展示计费事件;

接入信息流广告

一、创建NativeAd对象

      NativeAd nativeAds = NativeAd(this, config)//需要传activity,切记!!!

二、创建广告请求AdRequestConfig

       val config: AdRequestConfig = AdRequestConfig.Builder()
            .slotId(SCENE_ID) //广告场景id
            .widthDp(screenSizeDP[0]) //请求图片宽度dp值
            .heightDp(0) //请求图片高度dp值
            .requestCount(AD_COUNT_EACH_PAGE) //信息流广告请求条数
            .isVideoVoiceOn(false)
            /**
             * 设置视频自动播放场景:
             * ALWAYS - 所有网络环境均自动播放
             * WIFI - WIFI网络环境自动播放
             * NEVER - 所有网络环境均不会自动播放
             */
            .videoAutoPlayPolicy(AdRequestConfig.VideoAutoPlayPolicy.ALWAYS) //                .addSougouAdTemplate(AdTemplate.BIG_IMG_TPL_ID)
            //                .addSougouAdTemplate(AdTemplate.DOWNLOAD_BIG_TPL_ID)
            .showDownloadConfirmDialog(true)
            .isAdNeedRemoveDuplicates(true)
            .build()

三、请求广告

nativeAds!!.setListener(object : NativeAdsListener {
            override fun onAdReady(arrayList: List<NativeAdsResponse?>?) {
                listener?.onDataLoadResult(arrayList)
            }

            override fun onAdFailed(s: String) {
                listener?.onDataLoadResult(java.util.ArrayList<NativeAdsResponse?>())
                Toast.makeText(this@NativeActivity, "广告请求失败: $s", Toast.LENGTH_SHORT).show()
                Log.e("CLOOOUDAD", "NativeAd onAdFailed: $s")
            }
        })

四、展示广告

   // 信息流穿插广告
                val adsResponse: NativeAdsResponse = mDataList[position] as NativeAdsResponse
                if (holder is LargeImageViewHolder) {
                    holder.initViewHolderHeader(context, adsResponse)
                    if (adsResponse.imageUrls != null && adsResponse.imageUrls.size !== 0
                    ) {
                        val url: String = adsResponse.imageUrls[0]
                        GlideTool.load(context, url, holder.largeImage)
                    }
                    if (holder.closeBtn != null) {
                        holder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            holder.adContainer.visibility = View.GONE
//                            NativeActivity.closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    //判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (holder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            holder.download_item!!.visibility = View.VISIBLE
                            holder.AppName.text = adsResponse.downloadAppName
                            holder.AppVersion.text = adsResponse.appVersion
                            holder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            holder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
                            }
                            //权限说明点击
                            holder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    //权限弹框,需要客户端处理
                                    val PermissionsMap: Map<String, String> = adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is SmallImageViewHolder) {
                    val smallImageHolder = holder
                    smallImageHolder.initViewHolderHeader(context, adsResponse)
                    if (!TextUtils.isEmpty(adsResponse.desc)) {
                        smallImageHolder.desc2.text = adsResponse.desc
                    }
                    val url: String = adsResponse.imageUrls[0]
                    GlideTool.load(context, url, smallImageHolder.smallImage)
                    if (smallImageHolder.closeBtn != null) {
                        smallImageHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            smallImageHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                             notifyDataSetChanged()
                        }
                    }
                    //判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (smallImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            smallImageHolder.download_item!!.visibility = View.VISIBLE
                            smallImageHolder.AppName.text = adsResponse.downloadAppName
                            smallImageHolder.AppVersion.text = adsResponse.appVersion
                            smallImageHolder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            smallImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
                            }
                            //权限说明点击
                            smallImageHolder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框,需要客户端处理
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is GroupImageViewHolder) {
                    val groupImageHolder = holder
                    groupImageHolder.initViewHolderHeader(context, adsResponse)
                    val imageUrlList: List<String> = adsResponse.getImageUrls()
                    val imageNum = imageUrlList.size
                    if (imageNum > 0) {
                        groupImageHolder.adImage1.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[0], groupImageHolder.adImage1)
                    } else {
                        groupImageHolder.adImage1.visibility = View.GONE
                    }
                    if (imageNum > 1) {
                        groupImageHolder.adImage2.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[1], groupImageHolder.adImage2)
                    } else {
                        groupImageHolder.adImage2.visibility = View.GONE
                    }
                    if (imageNum > 2) {
                        groupImageHolder.adImage3.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[2], groupImageHolder.adImage3)
                    } else {
                        groupImageHolder.adImage3.visibility = View.GONE
                    }
                    if (groupImageHolder.closeBtn != null) {
                        groupImageHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            groupImageHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    //                    判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (groupImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            groupImageHolder.download_item!!.visibility = View.VISIBLE
                            groupImageHolder.AppName.text = adsResponse.downloadAppName
                            groupImageHolder.AppVersion.text = adsResponse.appVersion
                            groupImageHolder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            groupImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.privacyUrl)
                            }
                            //权限说明点击
                            groupImageHolder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is VideoViewHolder) {
                    val viewHolder = holder
                    viewHolder.initViewHolderHeader(context, adsResponse)
                    if (viewHolder.container != null) {
                        val videoView: View? = adsResponse.getVideoView(context)
                        if (videoView != null && videoView.parent !== viewHolder.container) {
                            val viewGroup = videoView.parent as ViewGroup?
                            viewGroup?.removeView(videoView)
                            val lp = RelativeLayout.LayoutParams(
                                RelativeLayout.LayoutParams.MATCH_PARENT,
                                RelativeLayout.LayoutParams.MATCH_PARENT
                            )
                            viewHolder.container!!.addView(videoView, lp)
                        }
                    }
                    if (viewHolder.closeBtn != null) {
                        viewHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            viewHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (viewHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            viewHolder.download_item!!.visibility = View.VISIBLE
                            viewHolder.AppName.text = adsResponse.downloadAppName
                            viewHolder.AppVersion.text = adsResponse.appVersion
                            viewHolder.DeveloperName.text = adsResponse.developerName
                            viewHolder.PrivacyUrl.setOnClickListener { v: View? ->
//                                NativeAd.UrlSkip(
//                                    this@NativeActivity,
//                                    adsResponse.getPrivacyUrl()
//                                )
                            }
                            viewHolder.Permissions.setOnClickListener { v: View? ->
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is ExpressNativeHolder) {
                    // 模板广告
                    val viewHolder = holder
                    adsResponse.setTTDefaultDislikeDialog(context as Activity?) //设置穿山甲SDK的dislike弹窗
                    viewHolder.mAdSource.text = adsResponse.adSource.getName()
                    if (viewHolder.container != null) {
                        //获取模板view
                        val video: View = adsResponse.expressAdView
                        if (video != null) {
                            if (video.parent != null) {
                                val viewGroup = video.parent as ViewGroup
                                viewGroup.removeView(video)
                            }
                            viewHolder.container!!.removeAllViews()
                            val lp = FrameLayout.LayoutParams(
                                FrameLayout.LayoutParams.MATCH_PARENT,
                                FrameLayout.LayoutParams.MATCH_PARENT
                            )
                            viewHolder.container!!.addView(video, lp)
                        }
                    }
                }
                // 注册原生信息流广告可点击区域视图,建议为客户端单个原生广告位所有区域,在广告展现时调用
                adsResponse.registerNativeClickableView(
                    holder.itemView as ViewGroup,
                    context,
                    holder.itemView as ViewGroup
                )

CAdInfo 说明

<table>
  <tr>
    <td><b>方法名</b></td>
    <td><b>说明</b></td>
  </tr>
  <tr>
    <td> int getNetworkFirmId() </td>
    <td> 返回竞价成功广告网络ID </td>    
  </tr>
  <tr>
    <td> String getAdsourceId() </td>
    <td> 返回竞价成功广告源ID </td>
  </tr>
  <tr>
    <td> double getEcpm() </td>
    <td> 返回竞价成功价格 </td>
  </tr>
</table>

接口说明

AdRequestConfig.Builder说明

广告请求参数

方法名 说明
slotId(String slotId) 聚合广告位ID
requestCount(int adCount) 请求广告数,最多不超过3个
widthDp(int width) 自渲染设置宽,单位dp
heightDp(int height) 模板设置高,单位dp
isVideoVoiceOn(boolean isVoiceOn) 视频播放是否有声音
videoAutoPlayPolicy(VideoAutoPlayPolicy policy) 置视频自动播放场景

NativeAdsResponse.NativeActionListener 说明

广告加载回调

方法名 说明
onAdClick() 广告点击回调
onAdShow(CAdInfo cAdInfo) 广告展示回调
onError(String error) 错误回调
onAdClose(String s) 广告关闭回调
onExpressRenderFail(String error) 模板渲染失败
onExpressRenderSuccess(View var1, float var2, float var3) 模板渲染成功
onExpressRenderTimeout() 模板渲染超时
onDislikeDialogShow() 取消反馈弹框回调
onDownloadConfirmDialogDismissed() 下载确认弹框关闭

NativeAdsResponse 说明

信息流广告对象

方法名 说明
String getTitle() 广告标题
String getDesc() 广告描述
int getSelfRenderAdMediaType() 自渲染广告媒体主类型
int getSelfRenderAdStyle() 自渲染广告样式
String getDspLogoUrl() 广告源角标
List getImageUrls() 广告图片Image list,返回的list可能为0个
int getInteractionType() 原生广告交互类型
String getLogoUrl() 原生信息流自渲染广告素材
String getImageUrl() 原生信息流自渲染广告素材
boolean isExpressAd() 判断是否是模板
render() 模板加载前调用
void registerNativeClickableView(ViewGroup viewGroup, Context context, View creativeViews) 注册原生信息流广告可点击区域视图
View getExpressAdView() 模板类型获取广告View
View getVideoView(Context context) 获取视频view
String getDownloadAppName() 下载App名称
int getInteractionType() 获取交互类型
String getAppVersion() 下载App版本
void onDestroy() 资源释放
String getDeveloperName() 下载应用开发者
String getPrivacyUrl() 下载应用隐私
Map getPermissionsMap() 下载应用权限(需判空)
String getPermissionInfoUrl() 下载应用权限链接(需判空)
class NativeActivity : AppCompatActivity() {

    val TAG = "NativeAD"

    // 每页信息流的数量
    private val NEWS_COUNT_EACH_PAGE = 1
    private val AD_COUNT_EACH_PAGE = 3

    private var AD_COUNT = 0

    private var mContext: Context? = null
    private var nativeAds: NativeAd? = null
    private var mNativeFeedList: RecyclerView? = null
    private var mRefreshLayout: SmartRefreshLayout? = null

    // 当前加载信息流位置
    private var mCurFeedListIndex = 0
    private var mCurPageIndex = 0
    private var mAdapter: NativeFeedAdapter? = null

    // 保存信息流列表数据
    private val mDataList = ArrayList<Any>()

    // 保存广告列表
    private val mAdList = ArrayList<NativeAdsResponse>()

    private var isShowDownloadConfirmDialog = false
    private var SCENE_ID: String? = "2323537"
    private var IS_FINISH = false

    companion object {
        private val mAppDownloadListenerMap: WeakHashMap<RecyclerView.ViewHolder, CAppDownloadListener> =
            WeakHashMap<RecyclerView.ViewHolder, CAppDownloadListener>()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_native)
        mContext = applicationContext
        getIntentData()
        isShowDownloadConfirmDialog =
            SharedPreferencesUtils.getParam(this, "isShowDownloadConfirmDialog", true) as Boolean

        mRefreshLayout = findViewById(R.id.refreshLayout)
        mNativeFeedList = findViewById<View>(R.id.recycler_view) as RecyclerView
        mNativeFeedList!!.layoutManager = LinearLayoutManager(this)

        val itemDecoration = DividerItemDecoration(this, DividerItemDecoration.VERTICAL)
        itemDecoration.setDrawable(resources.getDrawable(R.drawable.drawable_recyclerview_divider))
        mNativeFeedList!!.addItemDecoration(itemDecoration)

        mAdapter = NativeFeedAdapter(this,mDataList)
        mNativeFeedList!!.adapter = mAdapter

        mRefreshLayout!!.setOnRefreshListener(OnRefreshListener {
            mRefreshLayout!!.setEnableLoadMore(false)
            AD_COUNT = 0
            refreshData()
        })

        mRefreshLayout!!.setOnLoadMoreListener(OnLoadMoreListener {
            mRefreshLayout!!.setEnableRefresh(false)
            AD_COUNT = 0
            loadMoreData()
        })

        // 自动刷新
        mRefreshLayout!!.autoRefresh()
    }

    private fun getIntentData() {
        SCENE_ID = intent.getStringExtra("SCENE_ID")
        IS_FINISH = intent.getBooleanExtra("IS_FINISH", false)
    }

    /**
     * 列表上拉加载更多列表
     */
    private fun loadMoreData() {

        // 限制加载更多
        if (mCurPageIndex >= 10) {
            mRefreshLayout!!.setNoMoreData(true)
            mRefreshLayout!!.setEnableRefresh(true)
            return
        }
        loadFeedList(object : onDataLoadListener {
            override fun onDataLoadResult(dataList: List<NativeAdsResponse?>?) {
                val isAdEmpty = dataList.isNullOrEmpty()
                if (isAdEmpty) {
                    Toast.makeText(this@NativeActivity, "广告请求结果为空", Toast.LENGTH_SHORT)
                        .show()
                }
                // 填充数据
                mCurPageIndex++
                val tmpFeedList: MutableList<Any> = java.util.ArrayList()
                for (i in 0 until  NEWS_COUNT_EACH_PAGE) {
                    tmpFeedList.add(mCurFeedListIndex++.toString())
                }
                val random = Random()
                if (!isAdEmpty) {
                    val tmpAdList: MutableList<NativeAdsResponse> =
                        java.util.ArrayList<NativeAdsResponse>()
                    for (i in dataList!!.indices) {
                        val nativeAdResponse: NativeAdsResponse? = dataList[i]
                        nativeAdResponse?.let {
                            tmpAdList.add(nativeAdResponse)
                            // TODO 打印自渲染素材
                            if (!nativeAdResponse.isExpressAd) {
                                Log.e("CLOOOUD_POLY", "title: " + nativeAdResponse.title)
                                Log.e("CLOOOUD_POLY", "desc: " + nativeAdResponse.desc)
                                Log.e(
                                    "CLOOOUD_POLY",
                                    "mainMediaType: " + nativeAdResponse.selfRenderAdMediaType
                                )
                                Log.e(
                                    "CLOOOUD_POLY",
                                    "subMediaType: " + nativeAdResponse.selfRenderAdStyle
                                )
                                Log.e("CLOOOUD_POLY", "dspLogoUrl: " + nativeAdResponse.dspLogoUrl)
                                Log.e("CLOOOUD_POLY", "LogoUrl: " + nativeAdResponse.logoUrl)
                                Log.e("CLOOOUD_POLY", "ImageUrl: " + nativeAdResponse.imageUrl)
                                val imageUrls: List<String> = nativeAdResponse.imageUrls
                                if (imageUrls != null && imageUrls.isNotEmpty()) {
                                    for (index in imageUrls.indices) {
                                        Log.e(
                                            "CLOOOUD_POLY",
                                            "imageUrls[" + index + "]: " + imageUrls[index]
                                        )
                                    }
                                } else {
                                    Log.e("CLOOOUD_POLY", "imageUrls: empty")
                                }
                                Log.e("CLOOOUD_POLY", "  ")
                            }
                            nativeAdResponse.setNativeActionListener(object :
                                NativeAdsResponse.NativeActionListener {
                                override fun onAdClick() {
                                    Log.e("CLOOOUDAD", "NativeAd onAdClick")
                                }

                                override fun onAdShow(cAdInfo: CAdInfo?) {
                                    Log.e("CLOOOUDAD", "NativeAd onAdShow")
                                }

                                override fun onError(s: String) {
                                    Log.e("CLOOOUDAD", "NativeAd onError: $s")
                                }

                                override fun onAdClose(s: String) {
                                    Log.e("CLOOOUD", "NativeAd onAdClose: $s")
                                    onAdClosed(nativeAdResponse)
                                }

                                override fun onExpressRenderFail(s: String) {
                                    //渲染失败
                                    Toast.makeText(
                                        this@NativeActivity,
                                        "广告渲染失败: $s", Toast.LENGTH_SHORT
                                    ).show()
                                }

                                override fun onExpressRenderSuccess(view: View?, v: Float, v1: Float) {
                                    // 渲染成功
                                }

                                override fun onExpressRenderTimeout() {
                                    // 渲染超时
                                }

                                override fun onDislikeDialogShow() {}
                                override fun onDownloadConfirmDialogDismissed() {}
                            })
                            if (nativeAdResponse.isExpressAd) {
                                // 模板广告开始渲染
                                nativeAdResponse.render()
                            } else if (nativeAdResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                                // 自渲染下载类广告,可设置下载回调,刷新自渲染下载按钮 (针对应用自渲染下载按钮的场景)
                                nativeAdResponse.appDownloadListener = NativeAppDownloadListener(nativeAdResponse)
                            }
                            // 随机插入广告
                            tmpFeedList.add(
                                random.nextInt(NEWS_COUNT_EACH_PAGE),
                                nativeAdResponse!!
                            )
                        }
                    }
                    mAdList.addAll(tmpAdList)
                    mDataList.addAll(tmpFeedList)
                    mAdapter!!.notifyDataSetChanged()
                }
                mRefreshLayout!!.finishLoadMore()
                mRefreshLayout!!.setEnableRefresh(true)
                mRefreshLayout!!.setEnableLoadMore(true)
                Handler(Looper.getMainLooper()).postDelayed({
                    AD_COUNT++
                    if (AD_COUNT < NEWS_COUNT_EACH_PAGE) {
                        loadMoreData()
                    }
                }, 500)
            }

        })
    }

    /**
     * 列表下拉刷新更多数据
     */
    private fun refreshData() {
        loadFeedList(object : onDataLoadListener {
            override fun onDataLoadResult(dataList: List<NativeAdsResponse?>?) {
                val isAdEmpty = dataList.isNullOrEmpty()
                if (isAdEmpty) {
                    Toast.makeText(this@NativeActivity, "广告请求结果为空", Toast.LENGTH_SHORT)
                        .show()
                } else {
                    mCurPageIndex = 1
                    mCurFeedListIndex = 0
                    // 填充数据
                    val tmpFeedList: MutableList<Any> = java.util.ArrayList()
                    for (i in 0 until NEWS_COUNT_EACH_PAGE) {
                        tmpFeedList.add(mCurFeedListIndex++.toString())
                    }
                    val random = Random()
                    if (!isAdEmpty) {
                        val tmpAdList: MutableList<NativeAdsResponse> =
                            java.util.ArrayList<NativeAdsResponse>()
                        for (i in dataList!!.indices) {
                            val nativeAdResponse: NativeAdsResponse? = dataList[i]
                            nativeAdResponse?.let {
                                tmpAdList.add(nativeAdResponse)

                                // TODO 打印自渲染素材
                                if (!nativeAdResponse.isExpressAd) {
                                    Log.e("CLOOOUD_POLY", "title: " + nativeAdResponse.title)
                                    Log.e("CLOOOUD_POLY", "desc: " + nativeAdResponse.desc)
                                    Log.e(
                                        "CLOOOUD_POLY",
                                        "mainMediaType: " + nativeAdResponse.selfRenderAdMediaType
                                    )
                                    Log.e(
                                        "CLOOOUD_POLY",
                                        "subMediaType: " + nativeAdResponse.selfRenderAdStyle
                                    )
                                    Log.e(
                                        "CLOOOUD_POLY",
                                        "dspLogoUrl: " + nativeAdResponse.dspLogoUrl
                                    )
                                    Log.e("CLOOOUD_POLY", "LogoUrl: " + nativeAdResponse.logoUrl)
                                    val imageUrls: List<String> = nativeAdResponse.imageUrls
                                    if (imageUrls != null && imageUrls.isNotEmpty()) {
                                        for (index in imageUrls.indices) {
                                            Log.e(
                                                "CLOOOUD_POLY",
                                                "imageUrls[" + index + "]: " + imageUrls[index]
                                            )
                                        }
                                    } else {
                                        Log.e("CLOOOUD_POLY", "imageUrls: empty")
                                    }
                                    Log.e("CLOOOUD_POLY", "  ")
                                }
                                nativeAdResponse.setNativeActionListener(object :
                                    NativeAdsResponse.NativeActionListener {
                                   override fun onAdClick() {
                                        Log.e("CLOOOUDAD", "NativeAd onAdClick")
                                    }

                                    override fun onAdShow(cAdInfo: CAdInfo) {
                                        Log.e("CLOOOUD_POLY", "ecpm: " + cAdInfo.ecpm)
                                        Log.e("CLOOOUDAD", "NativeAd onAdShow")
                                    }

                                    override fun onError(s: String) {
                                        Log.e("CLOOOUDAD", "NativeAd onError: $s")
                                    }

                                    override fun onAdClose(s: String) {
                                        Log.e("CLOOOUDpoly", "NativeAd onAdClose: $s")
                                        onAdClosed(nativeAdResponse)
                                    }

                                    override fun onExpressRenderFail(s: String) {
                                        //渲染失败
                                        Toast.makeText(
                                            this@NativeActivity,
                                            "广告渲染失败: $s", Toast.LENGTH_SHORT
                                        ).show()
                                    }

                                    override fun onExpressRenderSuccess(view: View?, v: Float, v1: Float) {
                                        // 渲染成功
                                    }

                                    override fun onExpressRenderTimeout() {
                                        // 渲染超时
                                    }

                                    override fun onDislikeDialogShow() {}
                                    override fun onDownloadConfirmDialogDismissed() {}
                                })

                                // 设置下载回调,目前仅支持快手、穿山甲和广点通自渲染广告
                                if (nativeAdResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                                    nativeAdResponse.appDownloadListener = NativeAppDownloadListener(
                                        nativeAdResponse
                                    )
                                }
                                if (nativeAdResponse.isExpressAd) {
                                    nativeAdResponse.render()
                                }

                                // 随机插入广告
                                tmpFeedList.add(
                                    random.nextInt(NEWS_COUNT_EACH_PAGE),
                                    nativeAdResponse
                                )
                            }

                        }

                        // 回收旧广告
                        for (response in mAdList) {
                            response.onDestroy()
                        }
                        mAdList.clear()
                        mAdList.addAll(tmpAdList)
                        mDataList.clear()
                        mDataList.addAll(tmpFeedList)
                        mAdapter?.notifyDataSetChanged()
                    }
                }
                mRefreshLayout!!.finishRefresh()
                mRefreshLayout!!.setEnableRefresh(true)
                mRefreshLayout!!.setEnableLoadMore(true)
                Handler(Looper.getMainLooper()).postDelayed({
                    AD_COUNT++
                    if (AD_COUNT < NEWS_COUNT_EACH_PAGE) {
                        loadMoreData()
                    }
                }, 500)
            }
        })
        if (!IS_FINISH) {
            return
        }
        Handler(Looper.getMainLooper()).postDelayed({
            finish()
            if (nativeAds != null) {
                nativeAds!!.onDestroy()
            }
            // 回收广告资源
            if (mAdList != null) {
                for (ad in mAdList) {
                    ad.onDestroy()
                }
            }
        }, 65)
    }

    private fun loadFeedList(listener: onDataLoadListener?): NativeAd? {
        val screenSizeDP: IntArray = Util.getScreenSizeInDP(applicationContext)
        val dm = applicationContext.resources.displayMetrics
        val config: AdRequestConfig = AdRequestConfig.Builder()
            .slotId(SCENE_ID) //广告场景id
            .widthDp(screenSizeDP[0]) //请求图片宽度dp值
            .heightDp(0) //请求图片高度dp值
            .requestCount(AD_COUNT_EACH_PAGE) //信息流广告请求条数
            .isVideoVoiceOn(false)//视频播放是否有声音
            /**
             * 设置视频自动播放场景:
             * ALWAYS - 所有网络环境均自动播放
             * WIFI - WIFI网络环境自动播放
             * NEVER - 所有网络环境均不会自动播放
             */
            .videoAutoPlayPolicy(AdRequestConfig.VideoAutoPlayPolicy.ALWAYS) //                .addSougouAdTemplate(AdTemplate.BIG_IMG_TPL_ID)
            //                .addSougouAdTemplate(AdTemplate.DOWNLOAD_BIG_TPL_ID)
            .showDownloadConfirmDialog(true)
            .build()
        nativeAds = NativeAd(this, config)
        nativeAds!!.setListener(object : NativeAdsListener {
            override fun onAdReady(arrayList: List<NativeAdsResponse?>?) {
                listener?.onDataLoadResult(arrayList)
            }

            override fun onAdFailed(s: String) {
                listener?.onDataLoadResult(java.util.ArrayList<NativeAdsResponse?>())
                Toast.makeText(this@NativeActivity, "广告请求失败: $s", Toast.LENGTH_SHORT).show()
                Log.e("CLOOOUDAD", "NativeAd onAdFailed: $s")
            }
        })
        return nativeAds
    }

    interface onDataLoadListener {
        fun onDataLoadResult(dataList: List<NativeAdsResponse?>?)
    }

    /**
     * 点击关闭广告按钮,触发此方法刷新信息流列表
     *
     * @param response
     */
    private fun onAdClosed(response: NativeAdsResponse?) {
        if (response != null) {
            mDataList.remove(response)
            mAdapter?.notifyDataSetChanged()
        }
    }

    override fun onResume() {
        super.onResume()
        if (mAdList != null) {
            for (response in mAdList) {
                response.onResume()
            }
        }
    }

    class NativeFeedAdapter(c: Context?,mDataList: ArrayList<Any>) :
        RecyclerView.Adapter<RecyclerView.ViewHolder>() {
        private val layoutInflater: LayoutInflater
        // 保存信息流列表数据
        private var mDataList = ArrayList<Any>()

        // 信息流列表正文 - 非广告
        private val LIST_DATA_FEED_CONTENT = 1

        // 信息流原生广告 - 自渲染大图广告
        private val LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE = 2

        // 信息流原生广告 - 自渲染小图广告
        private val LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE = 3

        // 信息流原生广告 - 自渲染三图广告
        private val LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE = 4

        // 信息流原生广告 - 自渲染视频广告
        private val LIST_DATA_SELF_RENDER_AD_VIDEO = 5

        // 信息流原生广告 - 原生模板
        private val LIST_DATA_AD_EXPRESS = 6

        private var context: Context? = null

        init {
            layoutInflater = LayoutInflater.from(c)
            this.mDataList = mDataList
            this.context = c
        }

        override fun getItemCount(): Int {
            return mDataList?.size ?: 0
        }

        override fun getItemViewType(position: Int): Int {
            val obj: Any = mDataList[position]
            return if (obj is String) {
                LIST_DATA_FEED_CONTENT
            } else {
                val response: NativeAdsResponse = obj as NativeAdsResponse
                if (response.isExpressAd) {
                    LIST_DATA_AD_EXPRESS
                } else {
                    when (response.selfRenderAdMediaType) {
                        NativeAdsResponse.NATIVE_AD_MEDIA_TYPE_IMAGE -> return when (response.selfRenderAdStyle) {
                            NativeAdsResponse.NATIVE_AD_STYLE_LARGE_IMAGE -> LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
                            NativeAdsResponse.NATIVE_AD_STYLE_SMALL_IMAGE -> LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE
                            NativeAdsResponse.NATIVE_AD_STYLE_GROUP_IMAGE -> LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE
                            else -> {
                                val imageNum: Int = response.imageUrls.size
                                if (imageNum < 3) {
                                    LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
                                } else {
                                    LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE
                                }
                            }
                        }

                        NativeAdsResponse.NATIVE_AD_MEDIA_TYPE_VIDEO -> return LIST_DATA_SELF_RENDER_AD_VIDEO
                    }
                    LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE
                }
            }
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
            return when (viewType) {
                LIST_DATA_FEED_CONTENT ->                     // 信息流正文
                    FeedViewHolder(
                        layoutInflater.inflate(
                            R.layout.layout_feed_list_item,
                            parent,
                            false
                        )
                    )

                LIST_DATA_SELF_RENDER_AD_LARGE_IMAGE -> LargeImageViewHolder(
                    layoutInflater.inflate(
                        R.layout.layout_native_self_render_ad_large_image,
                        parent,
                        false
                    )
                )

                LIST_DATA_SELF_RENDER_AD_SMALL_IMAGE -> SmallImageViewHolder(
                    layoutInflater.inflate(
                        R.layout.layout_native_self_render_ad_small_image,
                        parent,
                        false
                    )
                )

                LIST_DATA_SELF_RENDER_AD_GROUP_IMAGE -> GroupImageViewHolder(
                    layoutInflater.inflate(
                        R.layout.layout_native_self_render_ad_group_image,
                        parent,
                        false
                    )
                )

                LIST_DATA_SELF_RENDER_AD_VIDEO ->                     // 自渲染视频广告
                    VideoViewHolder(
                        layoutInflater.inflate(
                            R.layout.layout_self_render_video_native_ad,
                            parent,
                            false
                        )
                    )

                LIST_DATA_AD_EXPRESS ->                     // 原生模板广告
                    ExpressNativeHolder(
                        layoutInflater.inflate(
                            R.layout.listitem_ad_native_express,
                            parent,
                            false
                        )
                    )

                else -> ExpressNativeHolder(
                    layoutInflater.inflate(
                        R.layout.listitem_ad_native_express,
                        parent,
                        false
                    )
                )
            }
        }

        override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
            if (holder is FeedViewHolder) {
                // 信息流正文
                holder.bindData(mDataList[position] as String)
            } else {
                // 信息流穿插广告
                val adsResponse: NativeAdsResponse = mDataList[position] as NativeAdsResponse
                if (holder is LargeImageViewHolder) {
                    holder.initViewHolderHeader(context, adsResponse)
                    if (adsResponse.imageUrls != null && adsResponse.imageUrls.size !== 0
                    ) {
                        val url: String = adsResponse.imageUrls[0]
                        GlideTool.load(context, url, holder.largeImage)
                    }
                    if (holder.closeBtn != null) {
                        holder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            holder.adContainer.visibility = View.GONE
//                            NativeActivity.closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    //判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (holder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            holder.download_item!!.visibility = View.VISIBLE
                            holder.AppName.text = adsResponse.downloadAppName
                            holder.AppVersion.text = adsResponse.appVersion
                            holder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            holder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
                            }
                            //权限说明点击
                            holder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    //权限弹框,需要客户端处理
                                    val PermissionsMap: Map<String, String> = adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is SmallImageViewHolder) {
                    val smallImageHolder = holder
                    smallImageHolder.initViewHolderHeader(context, adsResponse)
                    if (!TextUtils.isEmpty(adsResponse.desc)) {
                        smallImageHolder.desc2.text = adsResponse.desc
                    }
                    val url: String = adsResponse.imageUrls[0]
                    GlideTool.load(context, url, smallImageHolder.smallImage)
                    if (smallImageHolder.closeBtn != null) {
                        smallImageHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            smallImageHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                             notifyDataSetChanged()
                        }
                    }
                    //判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (smallImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            smallImageHolder.download_item!!.visibility = View.VISIBLE
                            smallImageHolder.AppName.text = adsResponse.downloadAppName
                            smallImageHolder.AppVersion.text = adsResponse.appVersion
                            smallImageHolder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            smallImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.getPrivacyUrl())
                            }
                            //权限说明点击
                            smallImageHolder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框,需要客户端处理
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is GroupImageViewHolder) {
                    val groupImageHolder = holder
                    groupImageHolder.initViewHolderHeader(context, adsResponse)
                    val imageUrlList: List<String> = adsResponse.getImageUrls()
                    val imageNum = imageUrlList.size
                    if (imageNum > 0) {
                        groupImageHolder.adImage1.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[0], groupImageHolder.adImage1)
                    } else {
                        groupImageHolder.adImage1.visibility = View.GONE
                    }
                    if (imageNum > 1) {
                        groupImageHolder.adImage2.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[1], groupImageHolder.adImage2)
                    } else {
                        groupImageHolder.adImage2.visibility = View.GONE
                    }
                    if (imageNum > 2) {
                        groupImageHolder.adImage3.visibility = View.VISIBLE
                        GlideTool.load(context, imageUrlList[2], groupImageHolder.adImage3)
                    } else {
                        groupImageHolder.adImage3.visibility = View.GONE
                    }
                    if (groupImageHolder.closeBtn != null) {
                        groupImageHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            groupImageHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    //                    判断是否是下载类广告
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (groupImageHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            //demo增加显示下载五要素布局
                            groupImageHolder.download_item!!.visibility = View.VISIBLE
                            groupImageHolder.AppName.text = adsResponse.downloadAppName
                            groupImageHolder.AppVersion.text = adsResponse.appVersion
                            groupImageHolder.DeveloperName.text = adsResponse.developerName
                            //隐私权限点击
                            groupImageHolder.PrivacyUrl.setOnClickListener { v: View? ->
                                //点击跳转url加载
//                                NativeAd.UrlSkip(this@NativeActivity, adsResponse.privacyUrl)
                            }
                            //权限说明点击
                            groupImageHolder.Permissions.setOnClickListener { v: View? ->
                                //头条特殊处理,当getPermissionInfoUrl没有返回时调用getPermissionsMap()获取权限键值对进行展示
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is VideoViewHolder) {
                    val viewHolder = holder
                    viewHolder.initViewHolderHeader(context, adsResponse)
                    if (viewHolder.container != null) {
                        val videoView: View? = adsResponse.getVideoView(context)
                        if (videoView != null && videoView.parent !== viewHolder.container) {
                            val viewGroup = videoView.parent as ViewGroup?
                            viewGroup?.removeView(videoView)
                            val lp = RelativeLayout.LayoutParams(
                                RelativeLayout.LayoutParams.MATCH_PARENT,
                                RelativeLayout.LayoutParams.MATCH_PARENT
                            )
                            viewHolder.container!!.addView(videoView, lp)
                        }
                    }
                    if (viewHolder.closeBtn != null) {
                        viewHolder.closeBtn!!.setOnClickListener {
                            Toast.makeText(
                                context,
                                "关闭广告",
                                Toast.LENGTH_SHORT
                            ).show()
                            viewHolder.adContainer.visibility = View.GONE
//                            closeNativeSelfRenderAd(adsResponse)
                            notifyDataSetChanged()
                        }
                    }
                    if (adsResponse.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                        if (viewHolder.download_item != null && !TextUtils.isEmpty(adsResponse.privacyUrl)) {
                            viewHolder.download_item!!.visibility = View.VISIBLE
                            viewHolder.AppName.text = adsResponse.downloadAppName
                            viewHolder.AppVersion.text = adsResponse.appVersion
                            viewHolder.DeveloperName.text = adsResponse.developerName
                            viewHolder.PrivacyUrl.setOnClickListener { v: View? ->
//                                NativeAd.UrlSkip(
//                                    this@NativeActivity,
//                                    adsResponse.getPrivacyUrl()
//                                )
                            }
                            viewHolder.Permissions.setOnClickListener { v: View? ->
                                if (!TextUtils.isEmpty(adsResponse.permissionInfoUrl)) {
//                                    NativeAd.UrlSkip(
//                                        this@NativeActivity,
//                                        adsResponse.getPermissionInfoUrl()
//                                    )
                                } else {
                                    val PermissionsMap: Map<String, String> =
                                        adsResponse.permissionsMap
                                    //权限弹框
                                    NativeAd.CSJPermissionSkip(context, PermissionsMap)
                                }
                            }
                        }
                    }
                } else if (holder is ExpressNativeHolder) {
                    // 模板广告
                    val viewHolder = holder
                    adsResponse.setTTDefaultDislikeDialog(context as Activity?) //设置穿山甲SDK的dislike弹窗
                    viewHolder.mAdSource.text = adsResponse.adSource.getName()
                    if (viewHolder.container != null) {
                        //获取模板view
                        val video: View = adsResponse.expressAdView
                        if (video != null) {
                            if (video.parent != null) {
                                val viewGroup = video.parent as ViewGroup
                                viewGroup.removeView(video)
                            }
                            viewHolder.container!!.removeAllViews()
                            val lp = FrameLayout.LayoutParams(
                                FrameLayout.LayoutParams.MATCH_PARENT,
                                FrameLayout.LayoutParams.MATCH_PARENT
                            )
                            viewHolder.container!!.addView(video, lp)
                        }
                    }
                }
                // 注册原生信息流广告可点击区域视图,建议为客户端单个原生广告位所有区域,在广告展现时调用
                adsResponse.registerNativeClickableView(
                    holder.itemView as ViewGroup,
                    context,
                    holder.itemView as ViewGroup
                )
            }
        }
    }

    /**
     * 信息流内容
     */
    class FeedViewHolder(v: View) : RecyclerView.ViewHolder(v) {
        var title: TextView

        init {
            title = v.findViewById<View>(R.id.feed_item_title) as TextView
        }

        fun bindData(data: String) {
            title.text = "信息流正文 $data"
        }
    }

    /**
     * 可下载广告 viewholder
     */
    open class DownloadableAdViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        protected var adPackageName: TextView
        protected var title: TextView
        protected var desc: TextView
        protected var adIcon: ImageView
        protected var downloadState: TextView
        protected var adCta: TextView

        init {
            adPackageName = itemView.findViewById(R.id.adPackageName)
            title = itemView.findViewById(R.id.adTitle)
            adIcon = itemView.findViewById(R.id.adIcon)
            desc = itemView.findViewById<View>(R.id.adDesc) as TextView
            downloadState = itemView.findViewById(R.id.adDownload)
            adCta = itemView.findViewById(R.id.adCta)
        }

        // 更新下载状态
        fun updateDownloadState(state: String?) {
            if (state != null) {
                downloadState.visibility = View.VISIBLE
                downloadState.text = state
            } else {
                downloadState.visibility = View.INVISIBLE
            }
        }

        // 更新下载状态
        fun initViewHolderHeader(context: Context?, response: NativeAdsResponse) {
            if (response.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_DOWNLOAD) {
                adIcon.visibility = View.VISIBLE
                GlideTool.load(context, response.logoUrl, adIcon)
                // 绑定
                if (!response.isExpressAd) {
                    val listener: CAppDownloadListener = response.appDownloadListener
                    if (listener is NativeAppDownloadListener) {
                        (listener as NativeAppDownloadListener).bindViewHolder(this)
                    }
                }
            } else if (response.interactionType === AdConfig.NATIVE_INTERACTION_TYPE_LANDINGPAGE) {
                adIcon.visibility = View.GONE
                adIcon.setImageBitmap(null)
                updateDownloadState("查看详情")
            }

            // 广点通广告有个CTA功能,可以控制btn的显示文字跟功能,产品线可以按需接入
//            String ctaText = response.getCtaText();
//            Log.i("12345678","CTA======"+ctaText);
//            // 将该View传递给广点通进行绑定
//            response.bindCtaView(adCta);
//            if (TextUtils.isEmpty(ctaText)) {
//                adCta.setVisibility(View.INVISIBLE);
//            } else {
//                adCta.setVisibility(View.VISIBLE);
//                adCta.setText(ctaText);
//                downloadState.setVisibility(View.INVISIBLE);
//            }
            if (!TextUtils.isEmpty(response.packageName)) {
                adPackageName.text = response.packageName
            } else {
                adPackageName.text = ""
            }
            if (!TextUtils.isEmpty(response.title)) {
                title.text = response.adSource.toString() + response.title
            } else {
                title.text = response.adSource.getName()
            }
            if (!TextUtils.isEmpty(response.desc)) {
                desc.text = response.desc
            } else {
                desc.text = ""
            }
        }
    }

    /**
     * 原生自渲染图文类广告
     */
    class LargeImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
        var largeImage: ImageView
        var closeBtn: View?
        var download_item: LinearLayout?
        var AppName: TextView
        var AppVersion: TextView
        var DeveloperName: TextView
        var PrivacyUrl: TextView
        var Permissions: TextView
        var adContainer: NativeSelfRenderAdContainer;
        init {

            adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
            largeImage = v.findViewById<View>(R.id.largeImage) as ImageView
            closeBtn = v.findViewById(R.id.adCloseBtn)
            download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
            AppName = v.findViewById<View>(R.id.AppName) as TextView
            Permissions = v.findViewById<View>(R.id.Permissions) as TextView
            AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
            DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
            PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
        }
    }

    /**
     * 原生自渲染图文类广告
     */
    class SmallImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
        var smallImage: ImageView
        var desc2: TextView
        var closeBtn: View?
        var download_item: LinearLayout?
        var AppName: TextView
        var AppVersion: TextView
        var DeveloperName: TextView
        var PrivacyUrl: TextView
        var Permissions: TextView

        var adContainer: NativeSelfRenderAdContainer;
        init {

            adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
            desc2 = v.findViewById<View>(R.id.adDesc2) as TextView
            closeBtn = v.findViewById(R.id.adCloseBtn)
            smallImage = v.findViewById<View>(R.id.smallImage) as ImageView
            download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
            AppName = v.findViewById<View>(R.id.AppName) as TextView
            Permissions = v.findViewById<View>(R.id.Permissions) as TextView
            AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
            DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
            PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
        }
    }

    /**
     * 原生自渲染图文类广告
     */
    class GroupImageViewHolder(v: View) : DownloadableAdViewHolder(v) {
        var adImage1: ImageView
        var adImage2: ImageView
        var adImage3: ImageView
        var closeBtn: View?
        var download_item: LinearLayout?
        var AppName: TextView
        var AppVersion: TextView
        var DeveloperName: TextView
        var PrivacyUrl: TextView
        var Permissions: TextView
        var adContainer: NativeSelfRenderAdContainer;
        init {

            adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
            closeBtn = v.findViewById(R.id.adCloseBtn)
            adImage1 = v.findViewById<View>(R.id.adImage1) as ImageView
            adImage2 = v.findViewById<View>(R.id.adImage2) as ImageView
            adImage3 = v.findViewById<View>(R.id.adImage3) as ImageView
            download_item = v.findViewById<View>(R.id.download_item) as LinearLayout
            AppName = v.findViewById<View>(R.id.AppName) as TextView
            Permissions = v.findViewById<View>(R.id.Permissions) as TextView
            AppVersion = v.findViewById<View>(R.id.AppVersion) as TextView
            DeveloperName = v.findViewById<View>(R.id.DeveloperName) as TextView
            PrivacyUrl = v.findViewById<View>(R.id.PrivacyUrl) as TextView
        }
    }

    /**
     * 原生自渲染视频类广告
     */
    class VideoViewHolder(v: View) : DownloadableAdViewHolder(v) {
        var container: RelativeLayout?
        var closeBtn: View?
        var download_item: LinearLayout?
        var AppName: TextView
        var AppVersion: TextView
        var DeveloperName: TextView
        var PrivacyUrl: TextView
        var Permissions: TextView
        var adContainer: NativeSelfRenderAdContainer;
        init {

            adContainer = v.findViewById<NativeSelfRenderAdContainer>(R.id.adContainer)
            container = v.findViewById(R.id.videoContainer)
            closeBtn = v.findViewById(R.id.adCloseBtn)

            download_item = v.findViewById<View>(R.id.ad_group_image_download) as LinearLayout
//            download_item = adDownload.findViewById<View>(R.id.download_item) as LinearLayout
            AppName = download_item!!.findViewById<View>(R.id.AppName) as TextView
            Permissions = download_item!!.findViewById<View>(R.id.Permissions) as TextView
            AppVersion = download_item!!.findViewById<View>(R.id.AppVersion) as TextView
            DeveloperName = download_item!!.findViewById<View>(R.id.DeveloperName) as TextView
            PrivacyUrl = download_item!!.findViewById<View>(R.id.PrivacyUrl) as TextView
        }
    }

    /**
     * 原生模板广告
     */
    class ExpressNativeHolder(v: View) : RecyclerView.ViewHolder(v) {
        var container: FrameLayout?
        var mAdSource: TextView

        init {
            container = v.findViewById<View>(R.id.iv_listitem_express) as FrameLayout
            mAdSource = v.findViewById(R.id.mAdSource)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        nativeAds?.onDestroy()

        // 回收广告资源
        if (mAdList != null) {
            for (ad in mAdList) {
                ad.onDestroy()
            }
        }
    }

    /**
     * 关闭原生自渲染广告
     *
     * @param response
     */
    private fun closeNativeSelfRenderAd(response: NativeAdsResponse) {
        mDataList.remove(response)
        mAdList.remove(response)
        response.onCloseBtnClicked()
    }

    /**
     * 广告下载回调
     */
    internal class NativeAppDownloadListener(response: NativeAdsResponse) :
        CAppDownloadListener {
        var viewHolder: DownloadableAdViewHolder? = null
        var adResponse: NativeAdsResponse

        init {
            adResponse = response
        }

        /**
         * 绑定回调
         *
         * @param holder
         */
        fun bindViewHolder(holder: DownloadableAdViewHolder?) {
            viewHolder = holder
            mAppDownloadListenerMap.put(viewHolder, this)
        }

       override fun onIdle() {
            if (isInvalidCallBack) {
                return
            }
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("立即下载")
            }
        }

        override fun onDownloadPaused() {
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("继续下载")
            }
        }

        override fun onProgressUpdate(i: Int) {
            if (isInvalidCallBack) {
                return
            }
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("下载 $i%")
            }
        }

        override fun onDownloadFinished() {
            if (isInvalidCallBack) {
                return
            }
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("点击安装")
            }
        }

        override fun onDownloadFailed() {
            if (isInvalidCallBack) {
                return
            }
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("下载失败")
            }
        }

        override fun onInstalled() {
            if (isInvalidCallBack) {
                return
            }
            if (viewHolder != null) {
                viewHolder!!.updateDownloadState("点击打开")
            }
        }

        private val isInvalidCallBack: Boolean
            private get() = mAppDownloadListenerMap.get(viewHolder) !== this
    }
}