11

私はすべての画像がネットワークからロードされ、iはfallowedた 、ページサイズが70アプリケーションがクラッシュする交差したときに、viewpagerで画像を150+示しています[リンク]:Strange out of memory issue while loading an image to a Bitmap objectOutofmemeoryerror(viewpager + imageviews)

と私ページスワイプが4に達するたびにリサイクルしています。012ページのアプリケーションで200MBのメモリを使用する場合は、

です。 。

私はそれを

私はスワイプすると、すべてのページを表示する必要があるの処理方法を、あなたからの助けを必要と...私もRuntime.getRuntimeを使用している

()GC();アプリのメモリがある場合

は、メモリを解放するにどのような方法で事前

+0

アプリケーション・メモリーまたはSDカードにネットワークからロードするビットマップを格納していますか? – user936414

+0

私はsdcardにビットマップを保存しています。 \t \t \t cacheDir =新しいファイル(sdDir、context.getString(R.string.cache_dir)); –

+0

ページに表示する画像の数はいくつですか?ビューごとに1つの画像のみ? – user936414

答えて

18

完全なソリューションは、以下の見つけることができる、重要な行は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

ClassCastExceptionに更新しました。 –

0

で50+ MB

おかげであなたがonCreateView()ビューの方法であなたのイメージをロードしていますか?達しますか

フレームワークは、このようにするときにメモリ管理要件を処理するようです。私は自分のイメージを自分のFragmentPageAdapterにロードして、フラグメント・コンストラクタにプリロードされているか、フラグメントinstaniateItemメソッドの一部として渡してみましたが、どちらも私にあなたが直面している問題を教えてくれました。最後に、各イメージをFragmentコンストラクタにロードするために必要な情報を渡してから、onCreateView()メソッドでこれらの詳細を使用しました。

マーク

+0

を解放(解放)する方法はありません。onCreateView()ビューメソッドで画像を読み込んでいません。すべての画像がinstantiateItem PagerAdapterにロードされています –

+0

は、アプリメモリを解放(リリース)する手段ですか?どの画像が使用されているのですか? –

+0

あなたのアプリが現在構造化されている方法は、すべての画像への参照を保持すると思いますので、とにかく小さいデバイスではいつでもメモリが使い果たされます。 onCreateViewメソッドに画像の作成を移動する必要があります。この方法では、フレームワークは3つの画像参照、つまり前の画像、現在表示されている画像、シーケンス内の次の画像だけを保持します。これらの画像は次のスワイプでスワップされ、画像の1つが3つのリストから外れ、別の画像がその場所に追加されます。 – Mark

0

Sheetal、

私は分で私の前に私のコードを持っていないが、それは次のようなものでなければなりません:

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

これはかなりありますそれは正確ではないかもしれませんが、かなり近いです。

さらに詳しいヘルプが必要な場合は、この回答にあなたを助けたと印を付けることを忘れないでください:)。

+1

サンプルコードを提供してくれてありがとうございます。私はあなたの助けが必要です。ページャを表示するにはどうすればいいですか?完全なサンプルコードのビューページとフラグメントを与えることができますか? –

+0

フラグメント化クラスでパラメータ化されたコンストラクタを使用しないでください –

4

メモリリークがあり、変数を二重にチェックし、大きなものに静的な変数を使用せず、可能な限り最終的に使用し、すべてのメンバーを非公開にしていると思います。

私はあなたがコミットを(またはあなたの現在のコードを保存する)ことをお勧めし、私が尋ねたことをしようとし、それが修正されるかどうかを確認してください。

のサンプルコードを使用すると、メモリリークを持っている場合、私は、多分あなたはどこかにgithubのか、Google Codeの上のようなコードを投稿することができますを言わせてしまう

ボトムライン:あなたは右のすべてをやっている可能性がありますが、変数はまだ保持していますガベージコレクタがそれらに触れることができないようにあなたの画像を参照してください。

私はメモリリークがあると言っていますが、これは起こりやすいので、これは最高の最高に起こることに気を付けてはいけません。

注:ネットワークアプリケーションから読み込んだデータの量が、正しく処理された場合、1ファイルのサイズを超える必要はありませんでした。

おかげ

+0

どのようにメモリリーク、 public restはprivateです –

0

Sheetal、

要求されたとして、次のように、私は上記のコードを使用します。

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

私FragmentActivityでは、私はのonCreate()メソッドに次の操作を行い

私のPagerAdapterで私は以下を行います:

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

そして、前の私の答えでコードを使用します。

これは明らかに完全なコードではなく、実際のコードから変更されていますが、何をすべきか、どこで行うべきかについての良いアイデアが与えられます。

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

これは、ガベージコレクションのためのImageViewのを解放する必要があります

マーク

+0

Mark、どのinstantiateItemが返すかこのステートメントではエラーが発生しています:return super.instantiateItem(container、position); // say:PagerAdapter型の抽象メソッドinstantiateItem(View、int)を直接呼び出すことはできません –

+0

Sheetal、あなたに私のコードをメールで送ることはできますか? – Mark

+0

確かに、私はあなたの電子メールのIDを与えることができるので、私はコード –

1

Sheetalは、あなたのコードを見た次試すことができます。