11

sto mostrando 150+ immagini in viewpager, quando le dimensioni della pagina attraversato 70 app si blocca, tutte le immagini si caricano dalla rete, e ho maggese [link]: Strange out of memory issue while loading an image to a Bitmap objectOutofmemeoryerror (viewpager + imageviews)

e io lo ricicla ogni volta che lo swiping della pagina raggiunge 4,

per l'applicazione di 70 pagine che richiede 200 MB di memoria. .

ho bisogno di aiuto da voi, come gestirlo

devo mostrare tutte le pagine con strisciata ...

ho usato anche Runtime.getRuntime() gc();

è un modo per liberare la memoria se la memoria applicazione è raggiunge i 50 + MB

grazie in anticipo

+0

Stai memorizzare i bitmap caricamento dalla rete nella memoria dell'applicazione o in sdcard? – user936414

+0

grazie per la riproduzione rapida, sto memorizzando bitmap in sdcard: File sdDir = android.os.Environment.getExternalStorageDirectory(); \t \t \t cacheDir = nuovo file (sdDir, context.getString (R.string.cache_dir)); –

+0

quante immagini visualizzate in una pagina? Solo un'immagine per visualizzazione? – user936414

risposta

18

La soluzione completa può essere trovato qui di seguito, le linee importanti sono quelle nel metodo destroyItem:

private class ContentPagerAdapter extends PagerAdapter { 
    @Override 
    public void destroyItem(View collection, int position, Object o) { 
     View view = (View)o; 
     ((ViewPager) collection).removeView(view); 
     view = null; 
    } 

    @Override 
    public void finishUpdate(View arg0) { 
     // TODO Auto-generated method stub 

    } 
    @Override 
    public int getCount() { 
     return ids.length; 
    } 

    @Override 
    public Object instantiateItem(View context, int position) { 
     ImageView imageView = new ImageView(getApplicationContext()); 
     imageView.findViewById(R.id.item_image); 
     imageView.setImageBitmap(BitmapFactory.decodeResource(getResources(), ids[position])); 

     ((ViewPager) context).addView(imageView); 

     return imageView; 
    } 

    @Override 
    public boolean isViewFromObject(View view, Object object) { 
     return view==((ImageView)object); 
    } 

    @Override 
    public void restoreState(Parcelable arg0, ClassLoader arg1) { 
     // TODO Auto-generated method stub 
    } 
    @Override 
    public Parcelable saveState() { 
     // TODO Auto-generated method stub 
     return null; 
    } 
    @Override 
    public void startUpdate(View arg0) { 
     // TODO Auto-generated method stub 

    } 
+0

ricevendo ClassCastException quando si utilizza View view = (View) o; –

0

viene caricata le immagini in) Metodo onCreateView (vista?

Il framework sembra occuparsi dei requisiti di gestione della memoria quando lo fa in questo modo. Avevo provato a caricare le mie immagini nel mio FragmentPageAdapter passandole nel mio costruttore Fragment precaricato o come parte del metodo Fragment instaniateItem ma entrambe mi hanno dato il problema che stai affrontando. Alla fine ho passato le informazioni necessarie per caricare ogni immagine nel costruttore di Fragment e poi ho usato questi dettagli nel metodo onCreateView().

Mark

+0

no, non sto caricando immagini nel metodo di visualizzazione onCreateView(). tutte le immagini vengono caricate in instantiateItem PagerAdapter –

+0

è un modo per liberare (rilasciare) la memoria dell'app? quali immagini stanno usando –

+0

Penso che il modo in cui la tua app sia strutturata al momento rimarrà un riferimento a tutte le immagini, quindi a un certo punto ti resterà a corto di memoria, specialmente su dispositivi più piccoli. È necessario spostare la creazione delle immagini nel metodo onCreateView, in questo modo il framework si limiterà a tre riferimenti di immagine, vale a dire l'immagine precedente, l'immagine attualmente visualizzata e l'immagine successiva nella sequenza. Queste immagini vengono sostituite al passaggio successivo, con una delle immagini che cade dall'elenco delle tre e un'altra che viene aggiunta al suo posto. – Mark

0

Sheetal,

non ho il mio codice di fronte a me al minuto ma dovrebbe essere qualcosa di simile a quanto segue:

public class MyFragment extends Fragment { 
    private Resources resources; // I load my images from different resources installed on the device 
    private int id; 

    public MyFragment() { 
    setRetainInstance(true); // this will prevent the app from crashing on screen rotation 
    } 

    public MyFragment(Resources resources, int id) { 
    this(); // this makes sure that setRetainInstance(true) is always called 
    this.resources = resources; 
    this.id = id; 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
    ImageView imageView = (ImageView)inflater.infale(R.layout.fragmentview, container, false); 
    imageView.setImageBitmap(BitmapFactory.decodeResource(resources, id)); 

    return imageView; 
    } 
} 

questo è praticamente dalla cima della mia testa, quindi potrebbe non essere esatto, ma è piuttosto vicino.

Se hai bisogno di ulteriore aiuto, basta gridare, non dimenticare di contrassegnare questa risposta come se ti avesse aiutato :).

+1

grazie al codice di esempio, ho bisogno di un po 'più di aiuto da te, come posso usare con esso il pager di visualizzazione, puoi dare codice di esempio completo viewpager e frammento –

+0

Non usare mai il costruttore parametrizzato in Framment classe –

4

Penso che questo accada perché si ha una perdita di memoria, si controllano le variabili, non si usa la vars statica per qualcosa di grande, si usa il finale quando possibile, si rendono privati ​​tutti i membri.

suggerisco di effettuare un commit (o salvare il codice corrente) e quindi provare a fare ciò che ho chiesto e vedere se lo risolve.

un esempio di codice avrebbe lasciate che vi dica se avete perdite di memoria, forse si può inviare il codice da qualche parte come su GitHub o Google Code

Linea di fondo: si potrebbe fare tutto per bene, ma una variabile detiene ancora una riferimento alle immagini in modo che il garbage collector non possa toccarle.

So che dire che hai una perdita di memoria fa male ma per favore non ti allarmare questo accade al meglio del meglio, perché è così facile che accada.

NOTA: Indipendentemente dalla grandezza dei dati che carico dalle app di rete non è mai necessario più della dimensione di 1 file se gestito correttamente.

Grazie

+0

come faccio a controllare le perdite di memoria, la variabile necessaria il resto pubblico è privato –

0

Sheetal,

Come richiesto, io uso il codice precedente come segue:

Nel mio FragmentActivity faccio quanto segue nella onCreate() Metodo:

pager = (ViewPager)findViewById(R.id.pager); 
imageAdapter = new MyPagerAdapter(this, pager, theResources, listOfIds.pageBitMapIds); 
imageAdapter.setRecentListener(this); 
pager.setAdapter(imageAdapter); 

Quindi nel mio PagerAdapter faccio quanto segue:

@Override 
public Object instantiateItem(ViewGroup container, int position) { 
    MyFragment myFragment = new MyFragment(resources, resourceIds[position], recentListener, position); 
    myFragments[position] = myFragment; 
    return super.instantiateItem(container, position); 
} 

@Override 
public Fragment getItem(int position) { 
    return myFragments[position]; 
} 

E quindi uso il codice nella mia precedente risposta sopra.

Questo ovviamente non è un codice completo ed è stato adattato dal mio codice attuale, ma dovrebbe darti una buona idea di cosa fare e dove farlo.

Mark

+0

Mark, che cosa restituisce istanza restituisce errore in questa istruzione: return super.instantiateItem (container, position); // dice: Impossibile richiamare direttamente il metodo astratto instantiateItem (View, int) per il tipo PagerAdapter –

+0

Sheetal, puoi inviarmi il tuo codice via email? – Mark

+0

sicuro, puoi dare il tuo indirizzo e-mail in modo che io possa spedire il codice –

1

Sheetal,

Dopo aver guardato il vostro codice è possibile provare i seguenti:

@Override 
public void destroyItem(View collection, int position, Object o) { 
    Log.d("DESTROY", "destroying view at position " + position); 
    View view = (View) o; 
    ((ViewPager) collection).removeView(view); 
    view = null; 
} 

Questo dovrebbe rilasciare l'ImageView per la garbage collection.