1

我使用NavigationDrawer瀏覽我的應用程序,此時Drawer包含一個具有ListView的片段(大約50行) 。按下時,每行顯示帶有4個選項卡的ViewPager(每個選項卡包含4個ImageView和一些文本)。現在,這裏的問題:當我從一個標籤到另一個刷卡,成長堆錯誤在logcat中顯示出來:Android,在片段內部加載多個ImageViews(使用UIL) - > Grow heap

04-12 12:53:25.810 9377-9377/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 13.650MB for 600016-byte allocation 
04-12 12:53:25.850 9377-9377/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 15.937MB for 2400016-byte allocation 
04-12 12:53:26.130 9377-9377/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 18.507MB for 1960016-byte allocation 
04-12 12:53:30.865 9377-9651/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 19.175MB for 557584-byte allocation 
04-12 12:53:31.470 9377-9439/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 19.693MB for 557584-byte allocation 
04-12 12:53:32.305 9377-9439/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 20.348MB for 557584-byte allocation 
04-12 12:53:34.225 9377-9441/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 21.794MB for 278800-byte allocation 
04-12 12:53:41.455 9377-9441/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 23.446MB for 557584-byte allocation 
04-12 12:53:44.650 9377-9651/com.mypd.wiki I/dalvikvm-heap﹕ Grow heap (frag case) to 24.002MB for 557584-byte allocation 

的ListView聽衆:

listView.setOnItemClickListener(new OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 
       Bundle bundle = new Bundle(); 
       bundle.putInt("id", position); 
       TabStripAdapter newFragment = new TabStripAdapter(); 
       newFragment.setArguments(bundle); 
       FragmentTransaction transaction = getFragmentManager().beginTransaction(); 
       transaction.replace(R.id.frame_container, newFragment); 
       transaction.addToBackStack(null); 
       transaction.commit(); 
      } 
     }); 

與適配器沿ViewPager:

public class TabStripAdapter extends Fragment { 
    CollectionPagerAdapter adapterViewPager; 
    ViewPager viewPager; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.models_list_adapter, container, false); 
     viewPager = (ViewPager) view.findViewById(R.id.pager); 
     adapterViewPager = new CollectionPagerAdapter(getFragmentManager()); 
     viewPager.setAdapter(adapterViewPager); 
     PagerSlidingTabStrip tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs); 
     tabs.setViewPager(viewPager); 

     return view; 
    } 

    public class CollectionPagerAdapter extends FragmentStatePagerAdapter { 

     SparseArray<Fragment> registeredFragments = new SparseArray<>(); 

     public CollectionPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 
     @Override 
     public int getCount() { 

      return 4; 
     } 
     @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); 
     } 
     @Override 
     public Fragment getItem(int position) { 
      switch (position) { 
       case 0: 
        Bundle bundle = getArguments(); 
        Tab1 frag1 = new Tab1().newInstance(); 
        frag1.setArguments(bundle); 
        return frag1; 
       case 1: 
        Bundle bundle1 = getArguments(); 
        Tab2 frag2 = new Tab2().newInstance(); 
        frag2.setArguments(bundle1); 
        return frag2; 
       case 2: 
        Bundle bundle2 = getArguments(); 
        Tab3 frag3 = new Tab3().newInstance(); 
        frag3.setArguments(bundle2); 
        return frag3; 
       case 3: 
        Bundle bundle3 = getArguments(); 
        Tab4 frag4 = new Tab4().newInstance(); 
        frag4.setArguments(bundle3); 
        return frag4; 
       default: 
        break; 
      } 
      return null; 
     } 

     public CharSequence getPageTitle(int position) { 
      switch (position) { 
       case 0: 
        return "Tab1"; 
       case 1: 
        return "Tab2"; 
       case 2: 
        return "Tab3"; 
       case 3: 
        return "Tab4"; 

       default: 
        return "None"; 
      } 
     } 
    } 
} 

這是怎麼我的標籤之一是這樣的:

public class Tab1 extends Fragment { 
     DisplayImageOptions options; 
     ImageView extraImg1; 
     ImageView extraImg2; 
     ImageView extraImg3; 
     ImageView extraImg4; 

     public Tab1 newInstance() { 
      return new Tab1(); 
     } 

     @Override 
     public void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      options = new DisplayImageOptions.Builder() 
        .showImageOnLoading(R.drawable.loading_audi) 
        .showImageForEmptyUri(R.drawable.ic_empty) 
        .showImageOnFail(R.drawable.ic_error) 
        .cacheInMemory(true) 
        .delayBeforeLoading(200) 
        .bitmapConfig(Bitmap.Config.RGB_565) 
        .imageScaleType(ImageScaleType.EXACTLY) 
        .considerExifParams(true) 
        .build(); 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, 
           Bundle savedInstanceState) { 
      View view = inflater.inflate(R.layout.tab_strip_1, container, false); 
      // Bundle setup: 
      Bundle bundle = this.getArguments(); 
      int position = bundle.getInt("id"); 

      if(bundle.containsKey("id")){ 

       position = bundle.getInt("id"); 
      } else { 
       this.getActivity().finish(); 
      } 

      // TextView setup: 
      TextView title = (TextView) view.findViewById(R.id.title); 
      title.setText("Tab1 design"); 
      TextView description = (TextView) view.findViewById(R.id.tab1); 
      description.setText(Data.Tab1[position]); 

      // ImageView setup: 
      extraImg1 = (ImageView) view.findViewById(R.id.extraImg1); 
      ImageLoader.getInstance().displayImage(Data.TabA[position], extraImg1, options); 
      // 
      extraImg2 = (ImageView) view.findViewById(R.id.extraImg2); 
      ImageLoader.getInstance().displayImage(Data.TabB[position], extraImg2, options); 
      // 
      extraImg3 = (ImageView) view.findViewById(R.id.extraImg3); 
      ImageLoader.getInstance().displayImage(Data.TabC[position], extraImg3, options); 
      // 
      extraImg4 = (ImageView) view.findViewById(R.id.extraImg4); 
      ImageLoader.getInstance().displayImage(Data.TabD[position], extraImg4, options); 

      return view; 
     } 
     @Override 
     public void onStart() { 
      super.onStart(); 
     } 
     @Override 
     public void onPause(){ 
      super.onPause(); 
     } 

     @Override 
     public void onResume(){ 
      super.onResume(); 
     } 

    // Here I try to recycle the ImageViews but I'm not sure I'm doing it right... 

     public static void recycleImagesFromView(View view) { 
      if(view instanceof ImageView) { 
       Drawable drawable = ((ImageView)view).getDrawable(); 
       if(drawable instanceof BitmapDrawable) 
       { 
        BitmapDrawable bitmapDrawable = (BitmapDrawable)drawable; 
        bitmapDrawable.getBitmap().recycle(); 
       } 
      } 

      if (view instanceof ViewGroup) { 
       for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
        recycleImagesFromView(((ViewGroup) view).getChildAt(i)); 
       } 
      } 
     } 
     @Override 
     public void onDestroy(){ 
      super.onDestroy(); 
      recycleImagesFromView(getView()); 
     } 
    } 

UIL配置:

public class UILApplication extends Application {  

... 

    public static void initImageLoader(Context context) { 

     ImageLoaderConfiguration.Builder config = new ImageLoaderConfiguration.Builder(context); 
     config.threadPriority(Thread.NORM_PRIORITY - 2); 
     config.threadPoolSize(3); 
     config.denyCacheImageMultipleSizesInMemory(); 
     config.memoryCache(new WeakMemoryCache()); 
     config.denyCacheImageMultipleSizesInMemory(); 
     config.diskCacheFileNameGenerator(new Md5FileNameGenerator()); 
     config.diskCacheSize(200 * 1024 * 1024); 
     config.tasksProcessingOrder(QueueProcessingType.LIFO); 
     config.writeDebugLogs(); // Remove for release app 

     // Initialize ImageLoader with configuration. 
     ImageLoader.getInstance().init(config.build()); 
    } 
} 

我的猜測是,我的內存泄漏的地方,無論我有一個適當的方式來回收ImageViews,要麼我失去了一些東西。

對不起我的英語技能。

回答

0

在onCreate()方法

.cacheInMemory(true) 

應更改爲

.cacheInMemory(false) 
+0

仍然得到成長堆錯誤,我昨天打了大部分由UIL提供的選項。 – Alec

相關問題