• viewPager--viewpager时,发生内存溢出OOM问题


    两个问题:
    1、如果图片达到500kb每张,你这个划屏会有顿卡;
    2、快速滑动有出现0.几秒的白屏。图片越大,顿卡越明显。

    回复parcool:500kb的背景算大的了,如果是想做图片墙,viewpager不适合,可以使用开源的图片墙工具,内存+硬盘缓存

    还有哦,你这个图片根本没有手动回收,依然会OOM!

       今天在制作应用某个功能的引导页时,使用了ViewPager进行页面切换,每个页面就放了一个ImageView,使用背景图来进行展示,由于多图(11张)的原因,导致了OOM问题,这里总结一下。

           代码如下:

    1. public class GuideActivity extends Activity implements OnPageChangeListener{  
    2.     private ViewPager viewPager;  
    3.     private GuideAdapter adapter;  
    4.     private LinearLayout dotContain;  
    5.     private Button btnSure;  
    6.     private List<View> mViews=new ArrayList<View>();  
    7.     private int[] mResIds=new int[]{  
    8.             R.drawable.step01,  
    9.             R.drawable.step02,  
    10.             R.drawable.step03,  
    11.             R.drawable.step04,  
    12.             R.drawable.step05,  
    13.             R.drawable.step06,  
    14.             R.drawable.step07,  
    15.             R.drawable.step08,  
    16.             R.drawable.step09,  
    17.             R.drawable.step10,  
    18.             R.drawable.step11  
    19.             };   
    20.     @Override  
    21.     protected void onCreate(Bundle savedInstanceState) {  
    22.         super.onCreate(savedInstanceState);  
    23.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
    24.         setContentView(R.layout.activity_guide);  
    25.         initViews();  
    26.         initDatas();  
    27.     }  
    28.     protected void initViews() {  
    29.         viewPager=(ViewPager) findViewById(R.id.vp_guide);  
    30.         dotContain=(LinearLayout) findViewById(R.id.layout_dot_contain);  
    31.         btnSure=(Button) findViewById(R.id.btn_sure);  
    32.           
    33.         adapter=new GuideAdapter(mViews);  
    34.     }  
    35.   
    36.     protected void initDatas() {  
    37.           
    38.         for (int i = 0; i < mResIds.length; i++) {  
    39.             ImageView img=new ImageView(this);  
    40.             //延迟设置图片,在PagerAdapter内设置,解决OOM问题  
    41.             /*ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(   
    42.                     ViewGroup.LayoutParams.MATCH_PARENT,   
    43.                     ViewGroup.LayoutParams.MATCH_PARENT); 
    44.             img.setBackgroundResource(mResIds[i]); 
    45.             img.setLayoutParams(params);*/  
    46.             mViews.add(img);  
    47.         }  
    48.         viewPager.setAdapter(adapter);  
    49.         viewPager.setOnPageChangeListener(this);  
    50.         viewPager.setCurrentItem(0);  
    51.         viewPager.setOffscreenPageLimit(1);  
    52.         dotContain.getChildAt(0).setSelected(true);  
    53.     }  
    54.     /** 
    55.      *  
    56.      * 2014-12-19 上午10:56:19 
    57.      * @param position 
    58.      * @TODO 改变底部图标状态 
    59.      */  
    60.     private void chageDotState(final int position){  
    61.         int count=dotContain.getChildCount();  
    62.         for (int i = 0; i < count; i++) {  
    63.             View view=dotContain.getChildAt(i);  
    64.             if(position%count==i){  
    65.                 view.setSelected(true);  
    66.             }else{  
    67.                 view.setSelected(false);  
    68.             }  
    69.         }  
    70.     }  
    71.     /** 
    72.      *  
    73.      * @Create_date 2014-12-19 上午11:09:48 
    74.      * @TODO 适配器 
    75.      */  
    76.     class GuideAdapter extends PagerAdapter{  
    77.         private List<View> views;  
    78.           
    79.         public GuideAdapter(List<View> views) {  
    80.             this.views = views;  
    81.         }  
    82.   
    83.         @Override  
    84.         public int getCount() {  
    85.             return views.size();  
    86.         }  
    87.   
    88.         @Override  
    89.         public boolean isViewFromObject(View arg0, Object arg1) {  
    90.             return arg0==arg1;  
    91.         }  
    92.   
    93.         @Override  
    94.         public void destroyItem(ViewGroup container, int position, Object object) {  
    95.             container.removeView(views.get(position));  
    96.         }  
    97.   
    98.         @Override  
    99.         public int getItemPosition(Object object) {  
    100.             return super.getItemPosition(object);  
    101.         }  
    102.           
    103.         @Override  
    104.         public Object instantiateItem(ViewGroup container, int position) {  
    105.             //在此设置背景图片,提高加载速度,解决OOM问题  
    106.             View view=views.get(position);  
    107.             int count=getCount();  
    108.             ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(    
    109.                     ViewGroup.LayoutParams.MATCH_PARENT,    
    110.                     ViewGroup.LayoutParams.MATCH_PARENT);  
    111.             view.setBackgroundResource(mResIds[position%count]);  
    112.             view.setLayoutParams(params);  
    113.             container.addView(view,0);  
    114.             return views.get(position);  
    115.         }  
    116.     }  
    117.   
    118.     @Override  
    119.     public void onPageScrollStateChanged(int arg0) {  
    120.           
    121.     }  
    122.     @Override  
    123.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
    124.           
    125.     }  
    126.     @Override  
    127.     public void onPageSelected(int arg0) {  
    128.         if(arg0<adapter.getCount()-1){  
    129.             dotContain.setVisibility(View.VISIBLE);  
    130.             btnSure.setVisibility(View.GONE);  
    131.             chageDotState(arg0);  
    132.         }else{  
    133.             dotContain.setVisibility(View.GONE);  
    134.             btnSure.setVisibility(View.VISIBLE);  
    135.         }  
    136.     }  
    137. }  

    代码中已经进行了说明。一开始,使用了一个for循环,将所有的ImageView设置了背景并添加到List<View>中,这样导致,一点进这个界面时,有点卡顿,并且有时还会出现OOM问题。

     

            解决办法就是:在for循环内只将ImageView对象添加到List<View>中,并不对其设置背景资源,将该步骤延迟到PagerAdapter$instantiateItem()中再进行设置。

            说明:页面过多会报OOM的原因是,当ImageView在调用setBackgroundResource时,底层会调用BitmapFactory.decodeResource进行解码,而这个过程是耗时的,也很容易就OOM了,因此在for循环内进行多图设置的话就导致卡顿甚至OOM了。

  • 相关阅读:
    C++ promise
    C++ shared_future
    C++包装对象packaged_task
    C++ wait_for
    assert
    虚函数表构建时机
    C++ timed_mutex
    C++异步async
    C++原子操作atomic
    C++ typeid获取类型信息
  • 原文地址:https://www.cnblogs.com/awkflf11/p/6033647.html
Copyright © 2020-2023  润新知