在ConstraintLayout中使用MoPubRecyclerAdapter和Facebook原生广告崩溃

时间:2020-04-13 00:33:24

标签: android facebook kotlin facebook-ads-api mopub

预期

预计MoPubRecyclerAdapter将使用已定义的RecyclerView来对本机Facebook ConstraintLayout单元进行膨胀。

已观察

错误 从Facebook原生广告创建的MoPubRecyclerAdapter的{​​{1}}间歇崩溃。 MoPub SDK forumMoPub Android Mediation GitHub存储库中已注意到此问题。

登录

ConstraintLayout

实施

facebook_native_ad_item.xml


Fatal Exception: java.lang.ClassCastException: androidx.constraintlayout.widget.ConstraintLayout cannot be cast to android.widget.RelativeLayout
       at com.mopub.nativeads.FacebookAdRenderer$FacebookNativeViewHolder.fromViewBinder(FacebookAdRenderer.java:139)
       at com.mopub.nativeads.FacebookAdRenderer.renderAdView(FacebookAdRenderer.java:58)
       at com.mopub.nativeads.FacebookAdRenderer.renderAdView(FacebookAdRenderer.java:28)
       at com.mopub.nativeads.NativeAd.renderAdView(NativeAd.java:166)
       at com.mopub.nativeads.MoPubStreamAdPlacer.bindAdView(MoPubStreamAdPlacer.java:433)
       at com.mopub.nativeads.MoPubRecyclerAdapter.onBindViewHolder(MoPubRecyclerAdapter.java:424)
       at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6781)
       at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6823)
       at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5752)
       at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6019)
       at androidx.recyclerview.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:286)
       at androidx.recyclerview.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:343)
       at androidx.recyclerview.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:359)
       at androidx.recyclerview.widget.GapWorker.prefetch(GapWorker.java:366)
       at androidx.recyclerview.widget.GapWorker.run(GapWorker.java:397)
       at android.os.Handler.handleCallback(Handler.java:873)
       at android.os.Handler.dispatchMessage(Handler.java:99)
       at android.os.Looper.loop(Looper.java:205)
       at android.app.ActivityThread.main(ActivityThread.java:6991)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)

SomeFragment.kt

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/native_outer_view"
    style="@style/AdContentCardStyle"
    android:layout_width="match_parent"
    android:layout_height="@dimen/cell_content_feed_height"
    android:textDirection="locale">

    <TextView
        android:id="@+id/native_title"
        style="@style/CellCreatorStyle"
        app:layout_constraintBottom_toBottomOf="@+id/guideline"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toLeftOf="@id/native_icon_image" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintBottom_toTopOf="@id/native_media_view"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/sponsored"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/sponsored"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/guideline" />

    <com.facebook.ads.AdIconView
        android:id="@+id/native_icon_image"
        android:layout_width="@dimen/native_icon_image_dimen"
        android:layout_height="@dimen/native_icon_image_dimen"
        android:paddingRight="@dimen/padding_tiny"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <com.facebook.ads.MediaView
        android:id="@+id/native_media_view"
        style="@style/AdCellPreviewImageStyle"
        android:contentDescription="@string/native_main_image"
        app:layout_constraintBottom_toTopOf="@id/native_text"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/sponsored" />

    <TextView
        android:id="@+id/native_text"
        style="@style/CellTitleStyle"
        app:layout_constraintBottom_toTopOf="@id/native_cta"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toBottomOf="@id/native_media_view"
        tools:text="@string/learn_more" />

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/native_ad_choices_relative_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="left"
        app:layout_constraintBottom_toBottomOf="@id/native_cta"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@id/native_cta" />

    <TextView
        android:id="@+id/native_cta"
        style="@style/NativeCtaStyle"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toBottomOf="@id/native_text"
        tools:text="@string/learn_more" />

</androidx.constraintlayout.widget.ConstraintLayout>

FeedApater.kt

adapter = FeedAdapter(feedViewModel, viewEvent)
moPubAdapter = MoPubRecyclerAdapter(
                    requireActivity(),
                    adapter,
                    MoPubNativeAdPositioning.MoPubServerPositioning())
            moPubAdapter.registerAdRenderer(FacebookAdRenderer(
                    FacebookViewBinder.Builder(fb_native_ad_item)
                            .titleId(native_title)
                            .textId(native_text)
                            .mediaViewId(native_media_view)
                            .adIconViewId(native_icon_image)
                            .adChoicesRelativeLayoutId(native_ad_choices_relative_layout)
                            .advertiserNameId(native_title)
                            .callToActionId(native_cta)
                            .build()))
            val viewBinder = ViewBinder.Builder(native_ad_item)
                    .titleId(native_title)
                    .textId(native_text)
                    .mainImageId(R.id.native_main_image)
                    .iconImageId(native_icon_image)
                    .callToActionId(native_cta)
                    .privacyInformationIconImageId(string.native_privacy_information_icon_image)
                    .build()
            moPubAdapter.registerAdRenderer(FlurryNativeAdRenderer(FlurryViewBinder(Builder(viewBinder))))
            moPubAdapter.registerAdRenderer(MoPubVideoNativeAdRenderer(
                    MediaViewBinder.Builder(fb_native_ad_item)
                            .mediaLayoutId(native_media_view)
                            .iconImageId(native_icon_image)
                            .titleId(native_title)
                            .textId(native_text)
                            .privacyInformationIconImageId(native_ad_choices_relative_layout)
                            .build()))
            moPubAdapter.registerAdRenderer(MoPubStaticNativeAdRenderer(viewBinder))
            moPubAdapter.setContentChangeStrategy(MOVE_ALL_ADS_WITH_CONTENT)
            contentRecyclerView.adapter = moPubAdapter

环境

图书馆

@ExperimentalCoroutinesApi
class FeedAdapter(val viewModel: FeedViewModel, val viewEvent: FeedViewEvent)
    : PagedListAdapter<Content, FeedAdapter.ViewHolder>(DIFF_CALLBACK) {

    class ViewHolder(private var binding: CellContentBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(viewModel: FeedViewModel, content: Content, onClickListener: OnClickListener) {
            binding.viewModel = viewModel
            binding.data = content
            binding.clickListener = onClickListener
            binding.executePendingBindings()
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        val binding = CellContentBinding.inflate(inflater, parent, false)
        return ViewHolder(binding)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        getItem(position)?.let { content ->
            holder.bind(viewModel, content, createOnClickListener(content, position))
        }
    }

    private fun createOnClickListener(content: Content, position: Int) = OnClickListener { view ->
}

Android级别

  • 8.1.0
  • 9
  • 10

设备

  • LG Q60
  • 像素3a
  • Redmi Note 5 Pro

尝试的解决方法

库版本已更新,其中MoPub SDK已更新为implementation("com.mopub:mopub-sdk-native-static:5.11.1@aar") { transitive = true } implementation("com.mopub:mopub-sdk-native-video:5.11.1@aar") { transitive = true } implementation 'com.facebook.android:audience-network-sdk:5.1.0' implementation 'com.mopub.mediation:facebookaudiencenetwork:5.1.0.0' implementation 'com.flurry.android:ads:12.1.0@aar' implementation 'com.flurry.android:analytics:12.1.0@aar' implementation 'com.mopub.mediation:flurry:11.4.0.0' ,Facebook受众网络已更新为5.12.0,Facebook中介已更新为5.8.0。将确定是否可以解决上述崩溃。

5.8.0.0

1 个答案:

答案 0 :(得分:0)

使用RelativeLayout代替ConstraintLayout

正如MoPub的工程师在此GitHub issue中指出的那样,Facebook中介尚不兼容ConstraintLayout

AdChoices图标的XML视图(ID为native_ad_choices_relative_layout)必须为RelativeLayout,这是因为4.99.0+版本的Facebook Audience Network SDK进行了内部更改。适配器在这里需要RelativeLayout

之前

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/native_ad_choices_relative_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="left"
        app:layout_constraintBottom_toBottomOf="@id/native_cta"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="@id/native_cta" />

之后

    <RelativeLayout
        android:id="@+id/native_ad_choices_relative_layout"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:gravity="left" />

文档:Setup Ad Renderers for Native Ads

示例:github.com/mopub/mopub-sdk-android