ViewPager加载图片ANR问题

2019-05-18  本文已影响0人  Fitz_e74a

问题

先来看一段代码,功能是实现App引导页

public class GuideActivity extends BaseActivity {

    private final int[] mDrawableInts = {R.drawable.bootpage_1, R.drawable.bootpage_2,
            R.drawable.bootpage_3};

    @BindView(R.id.vp_guide)
    ViewPager mVpGuide;

    @Inject
    SP mSP;
    private List<View> mViewList;
    PagerAdapter mPagerAdapter = new PagerAdapter() {

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

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            container.addView(mViewList.get(position));
            return mViewList.get(position);
        }

        @Override
        public void destroyItem(ViewGroup container, int position, Object object) {
            container.removeView(mViewList.get(position));
        }

        @Override
        public boolean isViewFromObject(View view, Object object) {
            return view == object;
        }
    };

    public static void startIntent(Context context) {
        Intent intent = new Intent(context, GuideActivity.class);
        context.startActivity(intent);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_guide);
        ButterKnife.bind(this);
        Application.getAppComponent().inject(this);
        initViewList();
        mVpGuide.setAdapter(mPagerAdapter);

    }

    private void initViewList() {

        mViewList = new ArrayList<>();
        for (int i = 0; i < mDrawableInts.length; i++) {
            View view = LayoutInflater.from(this).inflate(R.layout.guide_vp_layout, null);
            TextView button = view.findViewById(R.id.into_main_activity);
            ImageView imageView = view.findViewById(R.id.item_iv);
            imageView.setImageResource(mDrawableInts[i]);
            button.setOnClickListener(v->{
                mSP.putBoolean(Const.FIRST_OPEN_APP, false);
                MainActivity.startIntent(this);
                finish();
            });
            if (i == mDrawableInts.length - 1) {
                button.setVisibility(View.VISIBLE);
            } else {
                button.setVisibility(View.GONE);
            }
            mViewList.add(view);
        }
    }
}

上面这段代码猛一看,没什么问题,运行起来也没问题,可是再内存不足的机器上,会出现OOM的问题,出问题的代码如下

        ImageView imageView = view.findViewById(R.id.item_iv);
        imageView.setImageResource(mDrawableInts[i]);

问题原因是因为在for循环中设置图片,导致OOM

解决方法

将设置图片的位置从for循环中移到instantiateItem中即可,最终修改部分代码为

        @Override
        public Object instantiateItem(ViewGroup container, int position) {
            View view = mViewList.get(position);
            ImageView imageView = view.findViewById(R.id.item_iv);
            Glide.with(GuideActivity.this)
                    .load(mDrawableInts[position])
                    .asBitmap()
                    .centerCrop()
                    .into(imageView);
            container.addView(view);
            return mViewList.get(position);
        }

destroyItem 中不需要做处理,我曾经手动在此处进行图片的回收,会导致报 尝试使用已经回收的图片 的错误

                   Drawable drawable = img.getDrawable( );
                   if(drawable != null)
                    {
                            if(drawable instanceof BitmapDrawable)
                             {
                               BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable;
                                Bitmap bitmap = bitmapDrawable.getBitmap( );
                                if(bitmap != null)
                                   bitmap.recycle( );//这句是没必要的,加上会出错
                              }
                     }


上一篇 下一篇

猜你喜欢

热点阅读