ListView使用AsyncTask加载图像

时间:2012-12-03 15:59:18

标签: android image listview android-asynctask weak-references

我一直在阅读很多类似于我的问题的答案,但仍然无法解决我的问题。我有一个RSS阅读器项目,它使用AsyncTask类在后台加载图像。该程序有效,除非用户快速滚动,否则图像有时不会加载到我的行中。它们永远不会加载到错误的位置,如果用户快速滚动它们似乎就会被跳过。此外,在启动时,我的列表视图中只有2或1个图像加载到用户可以看到的4行中。

我知道问题与我使用的WeakReference对象有关,但我不确定如何以更好的方式实现它...

这是我的RssListAdapter,它也包含我的Async类。

public class RssListAdapter extends ArrayAdapter<JSONObject>
{
TextView textView;
ImageView imageView;
JSONObject jsonImageText;
ProgressDialog progressDialog;
Activity activity2;
View rowView;

public RssListAdapter(Activity activity, List<JSONObject> imageAndTexts)
{
    super(activity, 0, imageAndTexts);
    activity2 = activity;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{

    Activity activity = (Activity) getContext();
    LayoutInflater inflater = activity.getLayoutInflater();

    // Inflate the views from XML
    View rowView = (View) inflater
            .inflate(R.layout.image_text_layout, null);
    jsonImageText = getItem(position);

    // ////////////////////////////////////////////////////////////////////////////////////////////////////
    // The next section we update at runtime the text - as provided by the
    // JSON from our REST call
    // //////////////////////////////////////////////////////////////////////////////////////////////////
    textView = (TextView) rowView.findViewById(R.id.job_text);
    imageView = (ImageView) rowView.findViewById(R.id.feed_image);

    BitmapDownloaderTask task = new BitmapDownloaderTask();
    Spanned text;
    try
    {
        text = (Spanned) jsonImageText.get("text");
        textView.setText(text);
    }
    catch (JSONException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    task.execute();

    return rowView;

}

public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap>
{
    private String url;
    private RssListAdapter adapter;
    private WeakReference<ImageView> imageViewReference = null;

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params)
    {
        imageViewReference = new WeakReference<ImageView>(imageView);

        Bitmap img = null;

        try
        {

            if (jsonImageText.get("imageLink") != null)
            {

                System.out.println("XXXX Link found!");
                String url = (String) jsonImageText.get("imageLink");
                URL feedImage = new URL(url);

                HttpURLConnection conn = (HttpURLConnection) feedImage
                        .openConnection();
                InputStream is = conn.getInputStream();
                img = BitmapFactory.decodeStream(is);
            }

        }
        catch (MalformedURLException e)
        {
            // handle exception here - in case of invalid URL being parsed
            // from the RSS feed item
        }
        catch (IOException e)
        {
            // handle exception here - maybe no access to web
        }
        catch (JSONException e)
        {
            // textView.setText("JSON Exception");
        }
        return img;
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap)
    {
        if (isCancelled())
        {
            bitmap = null;
        }

        if (imageViewReference != null)
        {
            ImageView imageView = imageViewReference.get();
            if (imageView != null)
            {
                imageView.setImageBitmap(bitmap);
            }
        }

    }

    @Override
    // Before images are loaded
    protected void onPreExecute()
    {
        if (imageViewReference == null)
        {
            imageView.setImageResource(R.drawable.stub);
        }
    }

}
}

1 个答案:

答案 0 :(得分:1)

您应该查看有关如何有效加载和显示位图的官方Android“Displaying Bitmaps Efficiently”教程。它附带一个随时可用的代码。