clockbyte / admobadapter

It wraps your Adapter to display Admob native ads and banners in a ListView/RecyclerView data set. It based on the Yahoo fetchr project https://github.com/yahoo/fetchr
Apache License 2.0
237 stars 75 forks source link

IndexOutOfBoundException: Inconsistency detected. Invalid item position 3 #113

Closed Shajeel-Afzal closed 6 years ago

Shajeel-Afzal commented 6 years ago

Admobadapter version or commit: 1.2.6 Android compileSdkVersion: 27

I am getting a lot of Crash Reports in Crashlytics about IndexOutOfBoundException and users are also complaining it in the Google Play Store Reviews. I am using AdmobAdapter along with FirebaseUI library, Following is my code:

mAdapter = new FirebaseRecyclerAdapter<LiveScoreModel, RecyclerView.ViewHolder>(options) {

        public LiveVH mLiveVH;

        @Override
        protected void onBindViewHolder(RecyclerView.ViewHolder holder, int position, LiveScoreModel model) {
            mLiveVH = (LiveVH) holder;
            mLiveVH.setLiveMatchInfo(mAdapter.getItem(position));
        }

        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            mLiveVH = new LiveVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.live_match_item, parent, false));
            mLiveVH.setOnDiscussionClickListener(LiveScoreFragment.this);
            mLiveVH.setOnShareClickListener(LiveScoreFragment.this);
            return mLiveVH;
        }

        @Override
        public void onDataChanged() {
            super.onDataChanged();
            if (mAdapter.getItemCount() == 0) {
                mStatefulLayout.showEmpty();
            } else
                mStatefulLayout.showContent();
        }

        @Override
        public void onError(DatabaseError error) {
            super.onError(error);

            switch (error.getCode()) {
                case DatabaseError.DISCONNECTED:
                case DatabaseError.NETWORK_ERROR:
                    mStatefulLayout.showOffline();
                    break;

                case DatabaseError.PERMISSION_DENIED:
                    mStatefulLayout.showEmpty();
                    mStatefulLayout.setEmptyText(R.string.no_permission);
                    break;

                default: {
                    mStatefulLayout.showEmpty();
                    mStatefulLayout.setEmptyText(R.string.something_went_wrong_while_getting_scores);
                }
            }
        }
    };

       int listAdsLimit = 20;
        int adsFrequency = 3
        int firstAdIndex = 2

        List<BannerAdPreset> adPresets = new ArrayList<>();

            adPresets.add(new BannerAdPreset(getString(R.string.recyclerview_banner_ad_unit_1)));
            adPresets.add(new BannerAdPreset(getString(R.string.recyclerview_banner_ad_unit_2)));
            adPresets.add(new BannerAdPreset(getString(R.string.recyclerview_banner_ad_unit_4)));

        mAdapterWrapper = AdmobBannerRecyclerAdapterWrapper.builder(getActivity())
                .setFirstAdIndex(firstAdIndex < 2 ? 2 : firstAdIndex)
                .setNoOfDataBetweenAds(adsFrequency < 2 ? 2 : adsFrequency)
                .setLimitOfAds(listAdsLimit <= 1 ? 3 : listAdsLimit)
                .setTestDeviceIds(((GlobalApplication) getActivity().getApplication()).getTestDeviceIds())
                .setAdPresets(adPresets)
                .setAdapter(mAdapter)
                .build();

        mLiveScoreRV.setAdapter(mAdapterWrapper);

And following is my code for click handling:

LiveScoreModel item;
        if (mAdapterWrapper != null) {
            final AdmobAdapterCalculator adapterCalc = mAdapterWrapper.getAdapterCalculator();
            int fetchingAdsCnt = mAdapterWrapper.getFetchingAdsCount();
            int sourceCnt = mAdapterWrapper.getAdapter().getItemCount();
            position = adapterCalc.getOriginalContentPosition(position, fetchingAdsCnt, sourceCnt);

            item = mAdapter.getItem(position);
        } else {
            item = mAdapter.getItem(position);
        }

        MatchDiscussionActivity.start(getActivity(), item.getTeam1_name(), item.getTeam2_name(),
                (item.getYmid() == null || item.getYmid().isEmpty()) ? item.getMid() : item.getYmid());

And here is the full Crash Report:

Fatal Exception: java.lang.IndexOutOfBoundsException: Inconsistency detected. Invalid item position 3(offset:1).state:4 android.support.v7.widget.RecyclerView{63f5203 VFED..... ......ID 0,0-1080,1620 #7f0901e5 app:id/videos_fragment_recycler_view}, adapter:com.clockbyte.admobadapter.bannerads.AdmobBannerRecyclerAdapterWrapper@fabf85a, layout:android.support.v7.widget.GridLayoutManager@1805a8b, context:psl99.com.pakistan_super_league.MainActivity@70f2109
       at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5654)
       at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5589)
       at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5585)
       at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2231)
       at android.support.v7.widget.GridLayoutManager.layoutChunk(GridLayoutManager.java:556)
       at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)
       at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:610)
       at android.support.v7.widget.GridLayoutManager.onLayoutChildren(GridLayoutManager.java:170)
       at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3670)
       at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3129)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at android.view.View.measure(View.java:19759)
       at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1632)
       at android.view.View.measure(View.java:19759)
       at android.widget.LinearLayout.measureVertical(LinearLayout.java:911)
       at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
       at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
       at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:719)
       at android.support.design.widget.HeaderScrollingViewBehavior.onMeasureChild(HeaderScrollingViewBehavior.java:91)
       at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onMeasureChild(AppBarLayout.java:1361)
       at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:789)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
       at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
       at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1464)
       at android.widget.LinearLayout.measureVertical(LinearLayout.java:758)
       at android.widget.LinearLayout.onMeasure(LinearLayout.java:640)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:6122)
       at android.widget.FrameLayout.onMeasure(FrameLayout.java:185)
       at com.android.internal.policy.DecorView.onMeasure(DecorView.java:690)
       at android.view.View.measure(View.java:19759)
       at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2313)
       at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1400)
       at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1649)
       at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1288)
       at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6359)
       at android.view.Choreographer$CallbackRecord.run(Choreographer.java:873)
       at android.view.Choreographer.doCallbacks(Choreographer.java:685)
       at android.view.Choreographer.doFrame(Choreographer.java:621)
       at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:859)
       at android.os.Handler.handleCallback(Handler.java:754)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:163)
       at android.app.ActivityThread.main(ActivityThread.java:6342)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)

And these are the devices on which it is happening the most:

You can see it yourself here: http://crashes.to/s/f002ea5b038

screen shot 2018-03-06 at 9 24 57 am
kot331107 commented 6 years ago

Hi @Shajeel-Afzal Plz check if it could be related to your issue https://stackoverflow.com/questions/30220771/recyclerview-inconsistency-detected-invalid-item-position ?

Shajeel-Afzal commented 6 years ago

Thank you @kot331107, I'll try and update here.

kot331107 commented 6 years ago

@Shajeel-Afzal any update?

Shajeel-Afzal commented 6 years ago

@kot331107, I have disabled the ads for now. I'll update and let you know once I have Crash Reports.

Yura-Savchuk commented 6 years ago

I received the same crash. It occurred for me when when banner cannot be displayed because of lost internet connection or wrong configuration.

JuanNova commented 6 years ago

In my case I have solved that with the next line:recyclerView.setItemAnimator(null); In your case try to put mLiveScoreRV.setItemAnimator(null); before mLiveScoreRV.setAdapter(mAdapterWrapper); or when you initialize it.

kot331107 commented 6 years ago

@JuanNova thx

closing it for now ...

thirtyyuan commented 4 years ago

In my case I have solved that with the next line:recyclerView.setItemAnimator(null); In your case try to put mLiveScoreRV.setItemAnimator(null); before mLiveScoreRV.setAdapter(mAdapterWrapper); or when you initialize it.

What's the different?

mdevs7 commented 2 years ago

I also faced this problem. This problem occurred when we delete some positions without notifying RecyclerView. Finally I was solve my problem with this code binding.mRecyclerView.getRecycledViewPool().clear(); // to clear RecyclerView old cache. Use this code where you are showing your RecyclerView( in Activity, Fragment ). WARNING: use this code before adding ArrayList to RecyclerView. Otherwise, it throws an error. I hope it helps.