2013-08-09 3 views
5

Сначала я хотел бы сказать, что английский не мой родной язык. Поэтому, пожалуйста, простите мне мои ошибки.android viewpager из памяти

К моей проблеме: У меня есть ViewPager с 10 страницами и вкладками. Первое окно предназначено для настройки, а остальные вопросы.

Вы начинаете с первого вопроса, и я показываю изображение, если вы нажмете «да» «нет», то переходите на следующую страницу, где второе изображение отображается с другим вопросом.

Я получаю каждый раз ошибку oom (как я добираюсь до страницы 7). Я прочитал несколько подсказок об этом. Теперь я использую растровый декодер каждый раз, когда я привязываю изображение к моему ImageView. Но это не очень помогает. У меня все еще такая же проблема. Мой декодер имеет *.inPurgeable = true;

Я знаю, что есть возможность изменить ваш manifest.xml, чтобы разрешить больше размера кучи, но я думаю, что это только задержит ошибку. Может ли кто-нибудь просмотреть мой код, пожалуйста, и скажите мне, что я делаю неправильно. Потому что мне кажется, хорошо, но потому что я новичок в программировании я мог бы сделать некоторые большие ошибки :)

Мой ViewPager с адаптером:

public class WaldViewPager extends FragmentActivity implements ActionBar.TabListener { 

    private static AppSectionsPagerAdapter mAppSectionsPagerAdapter; 
    static private ViewPager mViewPager; 
    private static Context context; 
    public static int bitmap; 
    private int width, height; 
    private ViewGroup rootWald; 
    private static int textSize = 0; 
    private Dialog dialog; 
    public static int lastUsed = 1; 
    private static int ergebnis = 0; 
    private static int[] fragenListe = new int[8]; 
    private static int[] antworten = new int[9]; 

    public static void setErgebnis(int zahl){ 
     ergebnis = zahl; 
    } 

    public static int getErgebnis(){ 
     return ergebnis; 
    } 

    public static void setAntwort(int position, int antwort){ 
     antworten[position-1] = antwort; 
    } 

    public static int getAntwort(int position){ 
     return antworten[position-1]; 
    } 

    public static void setPage(int position){ 
     mViewPager.setCurrentItem(position, true); 
    } 

    public static int getPage(){ 
     return mViewPager.getCurrentItem(); 
    } 

    private void resetListe(){ 
     for(int i=0; i<fragenListe.length; i++){ 
      fragenListe[i]=0; 
     } 
    } 

    private void resetAntworten(){ 
     for(int i=0; i<antworten.length; i++){ 
      antworten[i]=0; 
     } 
    } 

    public static boolean getFrage(int position){ 
     if(fragenListe[position-2] == 1){ 
      return true; 
     }else{ 
      return false; 
     } 
    } 

    public static void setPageVisible(int position, boolean status){ 
     if(status == true){ 
      fragenListe[position-2] = 1; 
     }else if(status == false){ 
      fragenListe[position-2] = 0; 
     } 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main_viewpager); 
     overridePendingTransition(R.anim.fade_out, R.anim.fade_in); 
     mAppSectionsPagerAdapter = new AppSectionsPagerAdapter(getSupportFragmentManager()); 
     WaldViewPager.context = getApplicationContext(); 
     berechneSchriftgroese(); 
     setupHelpInfoDialog(); 
     resetListe(); 
     resetAntworten(); 

     rootWald = (ViewGroup) findViewById(R.id.toast_layout_root); 

     final ActionBar actionBar = getActionBar(); 
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); 
     actionBar.setLogo(R.drawable.fake); 

     mViewPager = (ViewPager) findViewById(R.id.pager); 
     mViewPager.setAdapter(mAppSectionsPagerAdapter); 
     mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { 

      @Override 
      public void onPageSelected(int position){ 
       actionBar.getTabAt(position).select(); 
       ViewParent root = findViewById(android.R.id.content).getParent(); 
       findAndUpdateSpinner(root, position); 
      } 

      private boolean findAndUpdateSpinner(Object root, int position){ 
       if (root instanceof android.widget.Spinner){ 
        Spinner spinner = (Spinner) root; 
        spinner.setSelection(position); 
        return true; 
       }else if (root instanceof ViewGroup){ 
        ViewGroup group = (ViewGroup) root; 
        if (group.getId() != android.R.id.content){ 
         for (int i = 0; i < group.getChildCount(); i++){ 
          if (findAndUpdateSpinner(group.getChildAt(i), position)){ 
           return true; 
          } 
         } 
        } 
       } 
       return false; 
      } 
     }); 

     for (int i = 0; i < mAppSectionsPagerAdapter.getCount(); i++) { 
      actionBar.addTab(actionBar.newTab().setText(mAppSectionsPagerAdapter.getPageTitle(i)).setTabListener(this)); 
     } 

     mViewPager.setCurrentItem(1, true); 
    } 

    @Override 
    public void onBackPressed() { 
     if (mViewPager.getCurrentItem() == 1) { 
      super.onBackPressed(); 
     } else { 
      mViewPager.setCurrentItem(1, true); 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     MenuInflater menuInflater = getMenuInflater(); 
     menuInflater.inflate(R.menu.bottom_bar_frage, menu); 
     return super.onCreateOptionsMenu(menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.menu_settings_frage: 
       if(mViewPager.getCurrentItem()==0){ 
        mViewPager.setCurrentItem(lastUsed, true); 
       }else{ 
        lastUsed = mViewPager.getCurrentItem(); 
        mViewPager.setCurrentItem(0, true); 
       } 
       return true; 
      case R.id.menu_info: 
       dialog.show(); 
       return true; 
      default: 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    private void setupHelpInfoDialog(){ 
     dialog = new Dialog(WaldViewPager.this); 
     dialog.requestWindowFeature(Window.FEATURE_NO_TITLE); 
     dialog.setCancelable(true); 
     dialog.setContentView(R.layout.dialog_info); 
     dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT)); 
     TextView text = (TextView) dialog.findViewById(R.id.dialog_ueberschrift); 
     text.setText("Bedienung der App"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text1); 
     text.setText("-Wischfunktion:"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text1_sub); 
     text.setText("Zum Navigieren können Sie entweder auf die Tabs zurückgreifen oder Sie wischen das Fenster links oder rechts"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text2); 
     text.setText("-Zoomfunktion:"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text2_sub); 
     text.setText("Wenn Sie auf das Bild klicken, können Sie es mit 2 Fingern vergrößern bzw. verkleinern"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text3); 
     text.setText("-Erklärungshilfe:"); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     text = (TextView) dialog.findViewById(R.id.dialog_text3_sub); 
     text.setMovementMethod(LinkMovementMethod.getInstance()); 
     text.setText(ClickableText.addClickablePart("Damit Sie wenig Zeit beim Suchen der Fremd/Fachwörtern verlieren, können Sie Wörter wie \u200EClypeus\u200E direkt hier nachschlagen", context, rootWald), BufferType.SPANNABLE); 
     if(MainViewPager.getTextSize()!=0){ 
      text.setTextSize(text.getTextSize()-MainViewPager.getTextSize()); 
     } 
     ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1); 
     ImageView bild = (ImageView) dialog.findViewById(R.id.dialog_bild1); 
     bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(), R.drawable.swipe)); 
     bild = (ImageView) dialog.findViewById(R.id.dialog_bild2); 
     bild.setImageBitmap(DecodeImage.decode(bild.getContext().getResources(), 
R.drawable.swipe_bild)); 
    } 

    @Override 
    public void onTabSelected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 
     mViewPager.setCurrentItem(tab.getPosition(), true); 
    } 

    @Override 
    public void onTabUnselected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void onTabReselected(Tab tab, FragmentTransaction ft) { 
     // TODO Auto-generated method stub 
    } 

AppSectionsPagerAdapter

public static class AppSectionsPagerAdapter extends FragmentStatePagerAdapter { 

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

     @Override 
     public Parcelable saveState() { 
      return null; 
     } 

     @Override 
     public Fragment getItem(int i) {   
      switch (i) { 
      case 0: 
       return new SettingsFrage(); 
      case 1: 
       return new FrageA(); 
      case 2: 
       return new FrageB(); 
      case 3: 
       return new FrageC(); 
      case 4: 
       return new FrageD(); 
      case 5: 
       return new FrageE(); 
      case 6: 
       return new FrageF(); 
      case 7: 
       return new FrageG(); 
      case 8: 
       return new FrageH(); 
      case 9: 
       return new FrageI(); 
      } 
      return null; 
     } 

     @Override 
     public int getCount() { 
      return 10; 
     } 

     @Override 
     public float getPageWidth(int position) { 
      if(position == 0){ 
       return super.getPageWidth(position)*0.6f; 
      } 
      return super.getPageWidth(position); 
     } 

     @Override 
     public CharSequence getPageTitle(int position) { 
      switch(position){ 
      case 0: 
       return "Settings"; 
      case 1: 
       return "Einkerbung"; 
      case 2: 
       return "Einbuchtung"; 
      case 3: 
       return "Farbe"; 
      case 4: 
       return "Stirndreieck"; 
      case 5: 
       return "Haare"; 
      case 6: 
       return "Beborstung"; 
      case 7: 
       return "Hinterhaupt"; 
      case 8: 
       return "Pigmentierung"; 
      case 9: 
       return "Mesosoma"; 
      } 
      return null; 
     } 
    } 

    public static Context getContext(){ 
     return WaldViewPager.context; 
    } 

    public static int getTextSize(){ 
     return textSize; 
    } 

    private void berechneSchriftgroese(){ 
     Display display = getWindowManager().getDefaultDisplay(); 
     Point size = new Point(); 
     display.getSize(size); 
     width = size.x; 
     height = size.y; 
     if(width<=480 || height<=480){ 
      textSize = 12; 
     } 
    } 

    @Override 
    protected void onPause() { 
     // TODO Auto-generated method stub 
     super.onPause(); 
     overridePendingTransition(R.anim.fade_out, R.anim.fade_in); 
    } 
} 

Один из моих вопрос:

public class FrageB extends Fragment implements OnClickListener{ 

    public static ImageView bild; 
    public static TextView ueberschrift, frage, frageZusatz1, frageZusatz2; 
    public static View viewA, viewB, viewC; 
    public static RadioButton auswahlA, auswahlB, auswahlC; 

    String stringUeberschrift = "Einbuchtung"; 
    String stringFrage = "Welche Form hat der Hinterrand des Kopfes?"; 
    String stringAuswahlA = "keine Delle"; 
    String stringAuswahlB = "Delle"; 
    String stringAuswahlC = "unsicher"; 
    String stringFrageZusatz1 = "keine Delle: nicht oder nur schwach eingebuchtet, keine deutliche Delle"; 
    String stringFrageZusatz2 = "Delle: tief eingebuchtet, deutliche Delle"; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.fake_frage, container, false); 
     ViewGroup root = (ViewGroup) v.findViewById(R.id.toast_layout_root); 

     bild = (ImageView) v.findViewById(R.id.frage_bild); 
     frage = (TextView) v.findViewById(R.id.frage_frage); 
     ueberschrift = (TextView) v.findViewById(R.id.frage_ueberschrift); 
     auswahlA = (RadioButton) v.findViewById(R.id.frage_auswahl1); 
     auswahlB = (RadioButton) v.findViewById(R.id.frage_auswahl2); 
     auswahlC = (RadioButton) v.findViewById(R.id.frage_auswahl3); 
     frageZusatz1 = (TextView) v.findViewById(R.id.frage_zusatz1); 
     frageZusatz2 = (TextView) v.findViewById(R.id.frage_zusatz2); 
     viewA = (View) v.findViewById(R.id.fake_view1); 
     viewB = (View) v.findViewById(R.id.fake_view2); 
     viewC = (View) v.findViewById(R.id.fake_view3); 

     auswahlC.setEnabled(false); 
     bild.setOnClickListener(this); 
     auswahlA.setOnClickListener(this); 
     auswahlB.setOnClickListener(this); 
     auswahlC.setOnClickListener(this); 
     auswahlA.setEnabled(false); 
     auswahlB.setEnabled(false); 
     bild.setClickable(false); 

     if(WaldViewPager.getFrage(2)){ 
      ZeigeFrage.unhide(2); 
     } 

     ueberschrift.setMovementMethod(LinkMovementMethod.getInstance()); 
     frage.setMovementMethod(LinkMovementMethod.getInstance()); 
     frageZusatz1.setMovementMethod(LinkMovementMethod.getInstance()); 
     frageZusatz2.setMovementMethod(LinkMovementMethod.getInstance()); 

     frageZusatz1.setText(ClickableText.addClickablePart(stringFrageZusatz1, WaldViewPager.getContext(), root), BufferType.SPANNABLE); 
     frageZusatz2.setText(ClickableText.addClickablePart(stringFrageZusatz2, WaldViewPager.getContext(), root), BufferType.SPANNABLE);  
     auswahlA.setText(stringAuswahlA); 
     auswahlB.setText(stringAuswahlB); 
     auswahlC.setText(stringAuswahlC); 
     ueberschrift.setText(ClickableText.addClickablePart(stringUeberschrift, WaldViewPager.getContext(), root), BufferType.SPANNABLE); 
     frage.setText(ClickableText.addClickablePart(stringFrage, WaldViewPager.getContext(), root), BufferType.SPANNABLE); 

     if(WaldViewPager.getTextSize()!=0){ 
      auswahlA.setTextSize(auswahlA.getTextSize()-WaldViewPager.getTextSize()); 
      auswahlB.setTextSize(auswahlB.getTextSize()-WaldViewPager.getTextSize()); 
      auswahlC.setTextSize(auswahlC.getTextSize()-WaldViewPager.getTextSize()); 
      ueberschrift.setTextSize(ueberschrift.getTextSize()-WaldViewPager.getTextSize()); 
      frage.setTextSize(frage.getTextSize()-WaldViewPager.getTextSize()); 
      frageZusatz1.setTextSize(frageZusatz1.getTextSize()-WaldViewPager.getTextSize()); 
      frageZusatz2.setTextSize(frageZusatz2.getTextSize()-WaldViewPager.getTextSize()); 
     } 

     return v; 
    } 

    @Override 
    public void setUserVisibleHint(boolean isVisibleToUser) { 
     super.setUserVisibleHint(isVisibleToUser); 

     if (isVisibleToUser) { 
      if(WaldViewPager.getFrage(2)){ 
       ZeigeFrage.unhide(2); 
      } 
     } 
    } 

    @Override 
    public void onClick(View v) { 
     if(v == bild){ 
      Intent intent = new Intent(WaldViewPager.getContext(), ShowImage.class); 
      WaldViewPager.bitmap = R.drawable.frage2; 
      startActivity(intent); 
     } 
     if(v == auswahlA){ 
      WaldViewPager.setAntwort(WaldViewPager.getPage(), 1); 
      WaldViewPager.setPageVisible(3, true); 
      WaldViewPager.setErgebnis(0); 
      WaldViewPager.setPage(3); 
     } 
     if(v == auswahlB){ 
      //coptoformica 
      WaldViewPager.setAntwort(WaldViewPager.getPage(), 2); 
      WaldViewPager.setErgebnis(2); 
      Intent intent = new Intent(WaldViewPager.getContext(), ErgebnisB.class); 
      startActivity(intent); 
     } 
     if(v == auswahlC){ 

     } 
    } 
} 

Мои decodeImage

public class DecodeImage { 

    public static Bitmap decode(Resources res, int resId){ 
     BitmapFactory.Options bfOptions=new BitmapFactory.Options(); 
     bfOptions.inDither = false; 
     bfOptions.inPurgeable = true;    
     bfOptions.inInputShareable = true; 
     bfOptions.inTempStorage = new byte[32 * 1024]; 
     return BitmapFactory.decodeResource(res, resId, bfOptions); 
    } 
} 

Я хотел бы получить любую помощь. не стесняйтесь запрашивать код. Это приложение отлично работает на некоторых устройствах, но на другом нет. должно быть что-то с изменением размера кучи, я думаю.

EDIT: нашел решение. ответ с bitmap.recycle() работает, но из-за моего искусства кода я ленился, чтобы многое изменить, и я использовал что-то еще.

за ViewPager андроида предоставляет

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
} 

я модернизировал линию

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) { 
     //if you can see the fragment 
    }else{ 
     //if you dont 
    } 
} 

в

@Override 
public void setUserVisibleHint(boolean isVisibleToUser) { 
    super.setUserVisibleHint(isVisibleToUser); 
    if (isVisibleToUser) { 
     //if you can see the fragment 
    }else{ 
     //if you dont 
     imageViewToDelete.setImageDrawable(null); //this is ImageView from Fragment 
    } 
} 

ПОМНИТЕ: setUserVisibleHint() устанавливается ухо лжец, чем onCreateView()

удачи

+0

см. Принятые ан-http://stackoverflow.com/questions/17990086/out-of-memory-while-creating-bitmaps-on-device/17990482#17990482 –

+0

и для утилизации растрового изображения http: // stackoverflow. com/questions/17744828/bitmap-and-outofmemory-in-android/17745049 # 17745049 –

+0

спасибо, я меняю код уже – vandyke

ответ

5

Для каждого ImageView вам придется вызвать recycle() метод. Итак, перед строкой:.

bild.setImageBitmap (DecodeImage.decode (bild.getContext() GetResources(), R.drawable.swipe_bild));

Вы должны поместить строку:..

((BitmapDrawable) bild.getDrawable()) getBitmap() перерабатывают();

Если проблема не устранена, это потому, что изображение слишком велико, и тогда вам придется сжать его

+0

спасибо за быстрый ответ, я попробую сейчас – vandyke

+0

как я могу избежать NullPointerException? – vandyke

+0

Мне нужно создать растровые держатели в начале, а затем посмотреть, являются ли они «нулевыми»? – vandyke

1

я столкнулся с той же проблемой и решить ее, как следует

Лучший пример приведен в андроида руководство разработчика, следуйте этому руководству шаг за шагом.

1.implement inJustDecodeBounds http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

2. Следуйте инструкции ниже для асинхронных и кэширования, вы также можете загрузить образец из той же ссылке. http://developer.android.com/training/displaying-bitmaps/display-bitmap.html

0

У меня было OutOfMemory ошибка в ViewPager с изображениями (720 * 1200). Комбинируя советы я нашел решение, которое работало для меня:

  • поместить изображения в drawable-nodpi категории (удалить из всех других рисуемых категорий)

  • декодирования вытяжку в растровое изображение с параметрами (inSampleSize = 1, ARGB_8888)

0

Я использовал Пикассо и имел т его проблема тоже ... Просто удалите фиктивный контент, который вы разместили в ImageView. Удалите тег src, поскольку вам это не понадобится с Picasso.

<ImageView 
     android:id="@+id/img" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:adjustViewBounds="true" 
     android:scaleType="centerCrop" 
     **android:src="@drawable/myDrawable"**/> 

Это происходит потому, вводимые коэффициент должен быть загружен, даже если заменить их Пикассо позже, и после того, как вы загрузили много изображений в ваш ViewPager, это приводит к тому, OutOfMemory.

Смежные вопросы