2013-08-09 16 views
5

per prima cosa vorrei dire che l'inglese non è la mia lingua madre. Quindi per favore perdonami i miei errori.android viewpager memoria esaurita

Per il mio problema: ho uno ViewPager con 10 pagine e schede. La prima finestra è per l'impostazione e le altre sono domande.

Si inizia con la prima domanda e si visualizza un'immagine, se si fa clic su "sì" "no", si passa alla pagina successiva in cui viene visualizzata la seconda immagine con un'altra domanda.

Ricevo ogni volta l'errore oom (come arrivo alla pagina 7). Ho letto alcuni suggerimenti su di esso ora uso il decodificatore bitmap ogni volta che lego l'immagine al mio ImageView. Ma questo non aiuta molto. Ho ancora lo stesso problema. Il mio decoder ha *.inPurgeable = true;

So che esiste un'opzione per modificare manifest.xml per consentire più dimensioni dell'heap ma ritengo che ritarderà solo l'errore. Qualcuno può consultare il mio codice per favore e dirmi qualcosa che sto sbagliando. Causa mi sembra bene, ma perché io sono nuovo di programmazione avrei potuto fare alcuni grandi errori :)

mio viewpager con l'adattatore:

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); 
    } 
} 

Uno dei miei domanda:

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){ 

     } 
    } 
} 

mio 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); 
    } 
} 

Apprezzerei qualsiasi aiuto. sentiti libero di chiedere oltre paci di codice. questa app funziona bene su alcuni dispositivi ma su altri no. deve essere qualcosa con la modifica della dimensione dell'heap credo.

EDIT: ha trovato la soluzione. la risposta con il bitmap.recycle() funziona ma a causa della mia arte del codice ero pigro a cambiare molto e ho usato qualcos'altro.

come per ViewPager Android vi dà

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

ho aggiornato la linea

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

a

@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 
    } 
} 

RICORDATE: setUserVisibleHint() è impostato orecchio Lier rispetto al onCreateView()

buona fortuna

+0

vedere accettato ans- http://stackoverflow.com/questions/17990086/out-of-memory-while-creating-bitmaps-on-device/17990482#17990482 –

+0

e per riciclare il bitmap http: // stackoverflow. it/questions/17744828/bitmap-and-outofmemory-in-android/17745049 # 17745049 –

+0

grazie, sto modificando il codice già – vandyke

risposta

5

Per ogni IMAGEVIEW si dovrà chiamare recycle() metodo. Quindi, prima della riga:

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

Devi mettere la linea:..

((BitmapDrawable) bild.getDrawable()) getBitmap() riciclare();

Se il problema persiste, è perché l'immagine è troppo grande e quindi si dovrà comprimere

+0

grazie per la risposta rapida, lo proverò ora – vandyke

+0

come posso evitare NullPointerException? – vandyke

+0

devo creare titolari di bitmap all'inizio e quindi guardare se sono "null"? – vandyke

0

Ho avuto OutOfMemory errore in ViewPager con immagini (720 * 1200). La combinazione di consigli ho trovato la soluzione, che ha funzionato per me:

  • immagini messo in drawable-nodpi categoria (rimuovere da tutte le altre categorie disegnabili)

  • decodifica drawable in bitmap con le opzioni (inSampleSize = 1, ARGB_8888)

0

stavo usando Picasso e avevo t il suo problema ... Basta cancellare il contenuto fittizio che hai inserito in ImageView. Cancellare il tag src, poiché non sarà necessario con 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"**/> 

Questo accade perché la drawable devono essere caricati anche se li si sostituisce di Picasso dopo, e dopo aver caricato molte immagini nella vostra ViewPager, provoca l'OutOfMemory.

Problemi correlati