0

シナリオ: ちょっとトリッキーだけど面白い。JSON 応答を返すリクエストを送信しました。この応答には、たとえば 10 個の JSON 要求 URL がさらに含まれます。

次に、これらの 10 個の URL にリクエストを送信すると、各 URL に 2 つの画像 URL が含まれます。つまり、合計20枚の画像です。

私の意図は、これらの画像をListViewできるだけ早くユーザーに表示することです。これは私が今までやってきたことです:

ステップ 1:ProgressDialogアクティビティが開始されるとすぐに、YouTube のように表示中の円をポップします。

ステップ 2: ANASYNC TASKで、10 個の JSON リクエストの URL を提供する最初のリクエストを送信します。このリクエストを送信し、存在するこれらの 10 個の URL を解析して保存すると、レスポンスになります。

ステップ 3:最初 (10 個中) から始めて、JSON 応答を返す要求を送信します。

ステップ 4:この応答を解析して 2 つの画像 URL を取得し、LinkedList に保存します。

ステップ 5:画像の実際のリンクができたので、進行状況ダイアログを閉じて画像を取得します。

ステップ 6:この画像は に保存されdrawableます。BaseAdapterというカスタムを作成しましImageAdapterArrayList<Drawable> mImages

ステップ 7: 以下ArrayListを使用して、受け取ったドローアブルを thisに保存します。adapter.mImages.add(drawable);

ステップ 8:次に呼び出すadapter.notifyDataSetChanged();これにより、画像を表示する準備が整うとすぐにリストビューが更新されます。

ステップ 9:ステップ 3 に戻り、さらに URL を処理します。

以下はコードです(不要なコードをすべてストライプ化):

アクティビティクラス

public class ImageViewer extends Activity {
    GridView gvImage;
    private ProgressDialog progressDialog;
    private final static Integer IMAGE_LIMIT = 10;
    private ImageAdapter adapter;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        try {
            setContentView(R.layout.ImageViewer);
            gvImage = (GridView) findViewById(R.id.gvImage);
            adapter = new ImageAdapter(this);
            gvImage.setAdapter(adapter);

            progressDialog = ProgressDialog.show(ImageViewer.this, "In Progress",
                    "Loading...", true, true, new DialogInterface.OnCancelListener() {

                        public void onCancel(DialogInterface dialog) {
                            finish();
                        }
                    });
            new SendRequest().execute(null);
        } catch (Exception e) {
        }
    }

    class SendRequest extends AsyncTask {
        protected Object doInBackground(Object... params) {
            try {
                HttpClient client = new DefaultHttpClient(httpParameters);
                HttpContext localContext = new BasicHttpContext();
                HttpGet httpGet = new HttpGet(BaseRequest_URL);

                JSONObject jsonResponse = null;

                HttpResponse httpResponse = client.execute(httpGet, localContext);
                if (httpResponse.getStatusLine().getStatusCode() == 200) {
                    HttpEntity entity = httpResponse.getEntity();
                    jsonResponse = getJSONObjectFromEntity(entity); //getJSONObjectFromEntity() will return JSONObject
                    processJSON(jsonResponse);
                }
                progressDialog.dismiss();
            } catch (Exception e) {
            }
            return null;
        }

        private void processJSON(JSONObject jsonResponse) throws JSONException {
            for (int i = 0; i < IMAGE_LIMIT; i++) {
                // Some JSON parsing. Output will be 'imageURL' which will be image URL
                displayImage(imageURL);
            }
        }

        public void displayImage(String uri150) {
            try {
                InputStream is = (InputStream) new URL(uri150).getContent();
                if(progressDialog.isShowing()){
                    progressDialog.dismiss();
                }
                Drawable d = Drawable.createFromStream(is, "image 150");
                adapter.mImages.add(d);
                handler.sendEmptyMessage(0); // Handler Below
            } catch (Exception e) {
            }
        }

        protected void onPostExecute(Object result) {
            super.onPostExecute(result);
        }
    }

    private Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            adapter.notifyDataSetChanged();
        };
    };
}

ImageAdapter クラス:

public class ImageAdapter extends BaseAdapter {
    Context context;
    public ArrayList<Drawable> mImages = new ArrayList<Drawable>();

    public ImageAdapter(Context c) {
        this.context = c;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView = new ImageView(context);
        try {
            imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
            imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
            imageView.setImageDrawable(mImages.get(position));
            imageView.setTag("Image" + position);
        } catch (Exception e) {
        }
        return imageView;
    }
}

質問:

  1. 私が見る方法ImageAdapterは、数回呼び出されます。他に減らす方法はありますか?

  2. ImageAdapter のコードを最適化するにはどうすればよいですか。

  3. 他に改善点はありますか?

4

4 に答える 4

1
  1. (最初の 2 つの質問) アダプターは、どの行 (リスト内のビュー) が表示されるかを制御するだけでなく、それをリサイクルします。アダプターでは、 getView は呼び出されるたびに新しいビューを作成しますが、古いビューが利用できない場合にのみ新しいビューを作成する必要があります。ここでMark Murphy (commonsware) のアダプタをチェックしてください

  2. コードでは、進行状況ダイアログ中にすべての画像がダウンロードされます。あなたのユーザーはおそらくそれらを最後まで見ることはなく、間違いなくあなたの記憶に負担をかけます. JSON と画像の両方を遅延読み込みすることをお勧めします (JSON を要求し、解析し、ユーザーが表示/スクロールするグリッドの量に応じて、非同期で画像を 1 つずつ読み込みます)。画像の遅延読み込みに関しては多くの議論があり、間違いなく Fedor's answerから始める必要があります。

于 2012-11-13T14:42:57.753 に答える
1

OutOfMemoryException取得できるため、画像をメモリに保存するのは間違いです。

画像とキャッシュの操作方法については、ビットマップの効率的な表示を参照してください。

于 2012-11-13T12:55:04.780 に答える
0

このライブラリを試してください。これは、layz の読み込みに非常に適しています。

于 2012-11-14T09:58:01.247 に答える
0

Android LazyImageLoading を検索するだけです

幸運を

于 2012-11-14T10:08:41.293 に答える