1

Я использую NavigationDrawer для навигации по моему приложению, на данный момент ящик содержит один фрагмент, который имеет ListView (с примерно 50 строками) , При нажатии каждая строка отображает ViewPager с 4 вкладками (каждый из них содержит 4 ImageViews и некоторый текст). Теперь вот проблема: когда я красть из вкладки в другую, Grow Heap ошибка появляется в 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()); 
     } 
    } 

УИЛ конфигурации:

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

все еще получает ошибку Grow Heap, я играл вчера с большинством из вариантов, предоставленных ИЮОЖЕ. – Alec