3

リストビューを含むアクティビティを行っています。リストビューは、サーバーから引き出された大きな XML から取り込まれます。私のシナリオでは、通常、SAX パーサーを使用して XML を解析し、解析されたデータを含む Vector (または同様の構造) を返します。問題は、xml が大きすぎて、Vector に含まれる要素が多すぎて、メモリ不足エラーが発生することです。また、xml にはダウンロード中の画像へのリンクが含まれているため、状況がさらに悪化します。

このような場合、メモリをどのように管理すればよいですか? ユーザーがリストビューの特定の行にスクロールしたときにのみ画像をロードできるかどうかを考えていました。

4

3 に答える 3

2

メモリ不足の例外の問題は、画像のロードです。に自分自身を入力するのAdapterに問題はないはずListViewです。

ビジネスアプリケーションでは、各行ListViewに2秒の9000レコードをロードしています。TextViewしたがって、データのサイズは問題にならないはずです。

を使用しAsyncTaskて、サーバーからデータをフェッチします。doInBackground()メソッドでアダプターを解析してデータを入力してから、でアダプターをonPostExecute()設定しListViewます。データサイズが問題にならないように、最初は画像を含めないようにしてください。

正しく読み込まれる場合はListView、画像にデータを入力する方法を見つけてください。この操作を行うには複数の方法があります。画像が何度も同じである場合は、「メモリにキャッシュ」の実装を試みる必要があります。そうでない場合は、バックグラウンドスレッドからの「遅延読み込み」で問題なく動作するはずです。

編集:

これは、バックグラウンドスレッドから画像をレイジーロードする方法に関する非常に優れた投稿/チュートリアルです。これは、Androidマーケットがすべてのアプリケーションを表示しているときに使用するのと「ほぼ」同じ手法です。GridView最初は灰色のアイコンがいくつかあり、その後突然アプリケーションの画像が表示されます。これはバックグラウンドスレッドから実行されます。正確な行がユーザーに表示されると、バックグラウンドスレッドがインターネットからそれをフェッチし、リストにデータを入力してメモリにキャッシュし、すぐに再び利用できるようにします。ListViewでの画像の遅延読み込み

于 2012-07-23T07:55:49.393 に答える
0

OutOfMemoryException は、画像が原因である可能性が最も高いです。

写真付きのホテルのリストを表示したいとしましょう。ホテル情報を XML 形式で取得し、リスト (または同様の構造) に保存します。ホテル クラスには次のようなメンバーがURL pictureURLあり、そのようなメンバーWeakReference<Drawable> pictureは必要になるまで null になります。

AsyncTaskgetView() メソッドでイメージのダウンロードを開始するようにリスト アダプタを作成し(picture が null を指している場合)、それをリスト内の ImageView と の両方に設定できますHotel.picture

Hotel.picture は弱参照であるため、画像が画面から消えると、ImageViews再利用さ れてメモリが解放されます。

getView メソッドには、次のようなものが含まれる場合があります。

private class MyCustomAdapter extends BaseAdapter {
    ...
    List<Hotel> hotelList;
    ...
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ...
        Hotel hotel = hotelList.get(position);
        ImageView ivHotelPic = //your image view from the list (child of 'view')
        ...
        if (hotel.picture == null || hotel.picture.get() == null){
            new DownloadImageTask(hotel,ivHotelPic).execute(hotel.pictureURL)
        }
        else{
            ivHotelPic.setImageDrawable( hotel.picture.get() );
        }

        return view; 
    }
}

private class DownloadImageTask extends AsyncTask<URL, Integer, Drawable> {
    Hotel hotel;
    ImageView imageView;

    DownloadImageTask(Hotel hotel,ImageView imageView){
        this.hotel = hotel;
        this.imageView = imageView; 
    }       

    protected Drawable doInBackground(URL... urls) {
         assert urls.length == 1;

         Drawable image = //download image from urls[0] (or hotel.pictureURL);

         return image;
    }

    protected void onPostExecute(Drawable result) {
        imageView.setImageDrawable(result);
        hotel.picture = new WeakReference<Drawable>(result);
    }
}

アクティビティが終了するまで画像を保持したい場合は、通常の参照を使用することもできますが、これにより、あまりにも多くの画像がダウンロードされたときに OutOfMemory が発生する可能性があります。

于 2012-07-23T08:21:09.493 に答える
0

serviceXML をサーバーから にプルするために使用しますdatabase。Google Playで見られるように、activityデータを遅延ロードします。CWAC EndlessAdapterdatabaseを参照してください。画像を埋め込むには、Android 用の Universal Image Loaderも参照 してください。listview

于 2012-07-23T07:50:29.617 に答える