android - Admob 横幅广告使我的 recyclerview 滞后

标签 android performance android-recyclerview admob

我在我的 Android 应用程序中展示横幅广告。我按照官方文档实现了 admob 横幅 contentView 广告,我成功加载了广告,但现在我的 recyclerview 开始像 hell 一样滞后。如果我从我的代码中删除广告,滚动就会变得流畅。请帮我解决这个问题。

这是我的 fragment 类

public class WallpaperFragment extends Fragment {

private RecyclerView recyclerView;
private DatabaseReference wallRef;
private String category;
private FirebaseAuth mAuth;

private final String CATEGORY = "Category";

private Context context;
private ArrayList<Object> modelList = new ArrayList<>();
private GridLayoutManager manager;

// The number of native ads to load and display.
public int NUMBER_OF_ADS = 5;

// List of native ads that have been successfully loaded.
private List<NativeAd> mNativeAds = new ArrayList<>();
private WallpaperAdapter adapter;

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fg_wallpaper, container, false);

    category = "Recent";
    init(view);
    Util.showDialog(context, "Loading wallpapers...");

    manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            return (position % (SPACE_BETWEEN_ADS + 1) == SPACE_BETWEEN_ADS) ? 2 : 1;
        }
    });

    setScrollListener();
    initializeFirebaseDatabase();

    return view;
}

private void init(View view) {
    context = getContext();
    MobileAds.initialize(context, getString(R.string.admob_app_id));
    wallRef = FirebaseDatabase.getInstance().getReference().child(WALL).child(CATEGORY).child(category).getRef();
    mAuth = FirebaseAuth.getInstance();

    recyclerView = view.findViewById(R.id.recyclerView);
    manager = new GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false);
    recyclerView.setLayoutManager(manager);
    recyclerView.addItemDecoration(new GridItemDecor(0));
    recyclerView.setHasFixedSize(true);
    recyclerView.setItemAnimator(null);
}

private void setScrollListener() {
    recyclerView.addOnScrollListener(new HidingScrollListener() {
        @Override
        public void onHide() {
            if (context instanceof ToolbarShowHideListener) {
                ((ToolbarShowHideListener) context).hideBottomNavigation();
            }
        }

        @Override
        public void onShow() {
            if (context instanceof ToolbarShowHideListener) {
                ((ToolbarShowHideListener) context).showBottomNavigation();
            }
        }
    });
}

private void initializeFirebaseDatabase() {
    mNativeAds.clear();
    wallRef.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            modelList.clear();
            for (DataSnapshot childDataSnapshot : dataSnapshot.getChildren()) {
                WallpaperModel model = childDataSnapshot.getValue(WallpaperModel.class);
                modelList.add(model);
            }

            NUMBER_OF_ADS = modelList.size() / 2;
            loadNativeAd();
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    });
}

private void loadNativeAd() {
    loadNativeAd(0);
}

private void insertAdsInMenuItems() {
    if (mNativeAds.size() <= 0) {
        return;
    }

    int offset = (modelList.size() / mNativeAds.size()) + 1;
    int index = 2;
    for (NativeAd ad : mNativeAds) {
        modelList.add(index, ad);
        index = index + offset;
    }
    if (adapter == null) {
        adapter = new WallpaperAdapter(context, modelList, Objects.requireNonNull(mAuth.getCurrentUser()).getUid(), true, WALLPAPER_FRAGMENT);
        recyclerView.setAdapter(adapter);
    } else {
        adapter.updateList(modelList);
    }
}

private void loadNativeAd(final int adLoadCount) {

    if (adLoadCount >= NUMBER_OF_ADS) {
        insertAdsInMenuItems();
        return;
    }

    AdLoader.Builder builder = new AdLoader.Builder(context, /*getString(R.string.ad_unit_id)*/"ca-app-pub-3940256099942544/2247696110");
    AdLoader adLoader = builder.forContentAd(new NativeContentAd.OnContentAdLoadedListener() {
        @Override
        public void onContentAdLoaded(NativeContentAd ad) {
            // A content ad loaded successfully, call this method again to
            // load the next ad in the items list.
            mNativeAds.add(ad);
            loadNativeAd(adLoadCount + 1);
        }
    }).withAdListener(new AdListener() {
        @Override
        public void onAdFailedToLoad(int errorCode) {
            // A native ad failed to load. Call this method again to load
            // the next ad in the items list.
            Log.e("MainActivity", "The previous native ad failed to load. Attempting to" +
                    " load another.");
            loadNativeAd(adLoadCount + 1);
        }
    }).build();

    // Load the Native Express ad.
    adLoader.loadAd(new AdRequest.Builder().addTestDevice("9F50A23B86C21B90330202FAECE3C331").build());
}

这是我的适配器类,

public class WallpaperAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

private Context context;
private int height, fragment_id;
private String uId;
private Animation fadeout, fadein;
private DatabaseReference favCheckRef;
private final String CATEGORY = "Category";
private ArrayList<Object> modelList;
private boolean showLikeBtn;

public WallpaperAdapter(Context context, ArrayList<Object> modelList, String uId, boolean showLikeBtn, int fragment_id) {
    this.context = context;
    this.modelList = modelList;
    this.uId = uId;
    this.showLikeBtn = showLikeBtn;
    height = context.getResources().getDisplayMetrics().heightPixels;
    fadeout = AnimationUtils.loadAnimation(context, R.anim.anim_fade_out);
    fadein = AnimationUtils.loadAnimation(context, R.anim.anim_fade_in);
    favCheckRef = FirebaseDatabase.getInstance().getReference().child(WALL).child(USER)
            .child(uId).child(FAVOURITES).getRef();
    this.fragment_id = fragment_id;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    switch (viewType) {
        case NATIVE_CONTENT_AD_VIEW_TYPE:
            View nativeContentLayoutView = LayoutInflater.from(
                    parent.getContext()).inflate(R.layout.ad_content,
                    parent, false);
            return new NativeContentAdViewHolder(nativeContentLayoutView);
        case MENU_ITEM_VIEW_TYPE:
            // Fall through.
        default:
            View dataView = LayoutInflater.from(context).inflate(R.layout.single_wallpaper_unit, parent, false);
            return new ViewHolder(dataView);
    }
}

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
    int viewType = getItemViewType(position);
    Util.dismissDialog();

    switch (viewType) {

         case NATIVE_CONTENT_AD_VIEW_TYPE:
            NativeContentAd contentAd = (NativeContentAd) modelList.get(position);
            populateAdView(contentAd, (NativeContentAdView) holder.itemView);
            break;

        case MENU_ITEM_VIEW_TYPE:
            // fall through
        default:
            final ViewHolder wallHolder = (ViewHolder) holder;
            WallpaperModel model = (WallpaperModel) modelList.get(position);

            wallHolder.wallpaper.getLayoutParams().height = (int) (height / 2.5);
            wallHolder.name.setText(model.getName());
            favCheck(wallHolder, model);
            Glide.with(wallHolder.wallpaper.getContext())
                    .load(model.getThumbnail())
                    .into(wallHolder.wallpaper);
            break;


    }
}

@Override
public int getItemViewType(int position) {
    Object recyclerViewItem = modelList.get(position);
    if (recyclerViewItem instanceof NativeContentAd) {
        return NATIVE_CONTENT_AD_VIEW_TYPE;
    }
    return MENU_ITEM_VIEW_TYPE;
}

@Override
public int getItemCount() {
    return modelList.size();
}
private void populateAdView(NativeContentAd ad,NativeContentAdView adView){
    ((TextView) adView.getHeadlineView()).setText(ad.getHeadline());
    List<NativeAd.Image> images = ad.getImages();

    if (images.size() > 0) {
        ((ImageView) adView.getImageView()).setImageDrawable(images.get(0).getDrawable());
    }
    adView.setNativeAd(ad);
}

public class ViewHolder extends RecyclerView.ViewHolder {

    TextView name;
    ImageView wallpaper, favouriteIcon;

    private ViewHolder(View itemView) {
        super(itemView);

        wallpaper = itemView.findViewById(R.id.wallpaper);
        name = itemView.findViewById(R.id.name);
        favouriteIcon = itemView.findViewById(R.id.favouriteIcon);
    }
}

public class NativeContentAdViewHolder extends RecyclerView.ViewHolder {
    NativeContentAdViewHolder(View view) {
        super(view);
        NativeContentAdView adView = (NativeContentAdView) view;
        adView.setHeadlineView(adView.findViewById(R.id.contentad_headline));
        adView.setImageView(adView.findViewById(R.id.contentad_image));
    }
}

最佳答案

您加载的是原生 express ,而不是横幅广告。

问题是广告有图片,就像一个普通的 viewholder,你必须处理图片的缓存,我看到你已经在使用 glide...

此外,显示您的广告 ID 也不是一个好主意。

最后一件事,NONE这一点很重要,因为原生快捷广告已被弃用,并且无论如何都不起作用。

另一种选择是使用 Native Ads Advance,但除非您有几百万次下载,否则您将无法使用它 - look here :

注意:Native Ads Advanced 目前仅面向一组有限的发布商发布。如果您有兴趣参与,请联系您的客户经理讨论可能性。

我建议使用一些广告提供商,例如 Appodeal支持原生广告。

关于android - Admob 横幅广告使我的 recyclerview 滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51177721/

相关文章:

android - 使用 DiffUtil 在 RecyclerView 上添加拖放

android - RecyclerView 不显示 Fragment 内的所有项目

android - 如果Android目录尚不存在,如何自动创建它

android - 在 MediaPlayer 中打开内容 ://media/external/[. ..] 需要 READ_EXTERNAL_STORAGE 权限?

java - 使用 Java 从 UNIX 时间戳转换为 "Today at: currentTime"

c - c中最有效的指针算术类型

android - 如何使用 Transfuse 检索 SharedPreferences 值

c# - 这两个使用 foreach 的 IEnumerable<T> 代码之间会有性能差异吗?

javascript - 反向循环真的更快吗?

android - 如何修复 fragment 中的RecyclerView.setLayoutManager NullPointerException