简体   繁体   English

ListView使用AsyncTask加载图像

[英]ListView Loading Images with AsyncTask

I have been reading through a lot of answers of questions that are similar to mine, but still having problem fixing my issue. 我一直在阅读许多类似于我的问题的答案,但是在解决我的问题时仍然遇到问题。 I have a project that is an RSS Reader that loads in images in the background with an AsyncTask class. 我有一个RSS读取器项目,该项目使用AsyncTask类在后台加载图像。 The program works, except if the user scrolls quickly then the images sometimes do not load in my rows. 该程序有效,除非用户快速滚动,否则有时图像不会加载到我的行中。 They never load in the incorrect spot, it just seems like they are skipped if the user scrolls quickly. 它们永远不会加载到错误的位置,如果用户快速滚动,它们似乎会被跳过。 Also, on start-up, only 2 or 1 of the images in my listview load out of the 4 rows that the user can see. 另外,在启动时,用户可以看到的4行中,我的列表视图中仅加载了2幅或1幅图像。

I know the problem has something to do with the WeakReference object that I use, but I am not sure how to implement it in a better way... 我知道问题与我使用的WeakReference对象有关,但是我不确定如何以更好的方式实现它。

This is my RssListAdapter, which contains my Async class as well. 这是我的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);
        }
    }

}
}

You should check the official Android " Displaying Bitmaps Efficiently " tutorial on how to load and display bitmaps efficiently. 您应该查看官方的Android“ 有效显示位图 ”教程,以了解如何有效地加载和显示位图。 It comes with a ready to use piece of code. 它带有一个随时可用的代码段。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM