Java.lang.IllegalStateException: The application P

2019-03-19 08:50发布

I am trying to use a static class to pass value to a view instead of using intent as I have to pass a large amount of data. Sometimes I get this error and couldn't find out what is the main reason

Error :-

java.lang.IllegalStateException: The application's PagerAdapter changed the adapter's contents without calling PagerAdapter#notifyDataSetChanged! Expected adapter item count: 101, found: 200

My Pager class

public class MemeDetailActivity extends AppCompatActivity implements OnDialogClickListner<Void> {
    private ViewPager mPager;
    private List<Datum> mList;
    private ScreenSlidePagerAdapter pagerAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_meme_detail);
        mList = DataResult.getInstance().getData();
        DataResult.getInstance().resetData();
        if (mList != null)
            startPager(selected_position);
        else
            Toast.makeText(this, "Error loading data", Toast.LENGTH_SHORT).show();
        // ATTENTION: This was auto-generated to implement the App Indexing API.
        // See https://g.co/AppIndexing/AndroidStudio for more information.
        client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
    }

    private void startPager(int position) {
        pagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager());
        mPager.setAdapter(pagerAdapter);
        pagerAdapter.notifyDataSetChanged();
        mPager.setOffscreenPageLimit(0);
        mPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                new Interactors(MemeDetailActivity.this).updateView(Util.getAccessToken(), mList.get(position).getId(), new OnFinishListner<ViewsRM>() {
                    @Override
                    public void onFinished(ViewsRM result) {

                    }

                    @Override
                    public void onFailed(String msg) {
                    }
                });
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });
        mPager.setCurrentItem(position);
    }

    public class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {
        SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

        public ScreenSlidePagerAdapter(FragmentManager fm) {
            super(fm);
        }


        //todo entry point 3 : showing the image in the viewpager
        @Override
        public Fragment getItem(int position) {
            Fragment fragment = new fragment_mypager_new();
            Bundle bundle = new Bundle();
            if (frmMyMemes)
                bundle.putParcelable("MY_DATA", myList);
            bundle.putSerializable("DATA", mList.get(position));
            fragment.setArguments(bundle);
            return fragment;
        }

        @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            Fragment fragment = (Fragment) super.instantiateItem(container, position);
            registeredFragments.put(position, fragment);
            return fragment;
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            registeredFragments.remove(position);
            super.destroyItem(container, position, object);
        }

        public Fragment getRegisteredFragment(int position) {
            return registeredFragments.get(position);
        }
    }

}

My static class

public class DataResult<T> {

    private static DataResult instance;
    private List<T> data = null;

    protected DataResult() {

    }

    public static synchronized DataResult getInstance() {
        if (instance == null) {
            instance = new DataResult();
        }
        return instance;
    }

    public List<T> getData() {
        return data;
    }

    public void setData(List<T> data) {
        this.data = data;
    }

    public void resetData() {
        data = null;
    }
}

How I call the activity

    Intent intent = new Intent(getActivity(), MemeDetailActivity.class);
    DataResult.getInstance().setData(mListA);

5条回答
别忘想泡老子
2楼-- · 2019-03-19 08:55

Sometimes this error occurs.

Here is my suggestion:

In your DataResult->getData()

return a copy of the data.

DataResult is a singleton and holds the data. When your view gets the data, the view gets the data reference witch the DataResult is holding. Then setData() would change the data reference. Here comes the IllegalStateException.

Hope it would work :)

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-03-19 08:57

look at your code:

 @Override
        public int getItemPosition(Object object) {
            return POSITION_NONE;
        }

this code is use to refresh view when view change. it is also called notifyDataSetChanged()

its optional ovverride method so you can remove it.

Take a look at this answer: ViewPager PagerAdapter not updating the View

or else you can Change the FragmentStatePagerAdapter to FragmentPagerAdapter

查看更多
劫难
4楼-- · 2019-03-19 08:59

try using the following way:

mList=new ArrayList<Datum>();
        mList.addAll(DataResult.getInstance().getData());
        DataResult.getInstance().resetData();
查看更多
Root(大扎)
5楼-- · 2019-03-19 09:15

I think your DataResult class is not necessary.

According to your comment you are getting the error while you are updating the data set. I think you are getting data from some REST API or another web service. Then assign the data you gets from the API to a temporary Array List and update that temporary array list while you are getting new data. Don't touch the mListA variable until you finish receiving data. After complete getting data from the API assign the temporary array list you used to mListA directly in one line.

mListA = tmpList;

Then again call

mList = mListA;
pagerAdapter.notifyDataSetChanged();

This should solve your error.

查看更多
干净又极端
6楼-- · 2019-03-19 09:17

It may because you first setAdapter() and notifyDataSetChanged in method initUI();

Then, you instantiate the List<?> data in method initData(), the two methods in different lifetime of fragment.

It's the problem about fragment's lifecycle

查看更多
登录 后发表回答