Android - 异步下载图像并显示它

时间:2016-02-14 16:40:25

标签: java android

这是代码,图像确实是下载但问题是我无法显示它因为无法解析方法findViewById

public class ImageDownloader
    extends AsyncTask<String, Integer, Bitmap> {

protected void onPreExecute(){
    //Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
    //this where i get the image using HttpURLConnection 
}
protected void onProgressUpdate(Integer... params){
    //Update a progress bar here, or ignore it, it's up to you
}
protected void onPostExecute(Bitmap img){
    //here is the problem with findViewById beeing undefined
    ImageView image_view = (ImageView) findViewById(R.id.remote_image);

    if(image_view!=null && img!=null){
        image_view.setImageBitmap(img);
    }
}

在我的主要活动中,我在OnCreate中调用ImageDownloader,如下所示:

 ImageDownloader download = new ImageDownloader();
 download.execute("http://wanderingoak.net/bridge.png");

`

3 个答案:

答案 0 :(得分:3)

要访问findViewById,您需要一个实际的视图。您只能在ActivityFragmentView类中使用该方法。

传入引用,不要做你的类不应该做的事情:

// add the constructor
public ImageDownloader(ImageView image) {
    mImage = image;
}

然后调用构造函数:

ImageDownloader download = new ImageDownloader((ImageView) findViewById(R.id.remote_image));

clean 解决方案还应该使用WeakReference<ImageView>而不是ImageView,因为在长时间运行的任务中保留引用会导致内存泄漏。

使用AsyncTask作为非静态内部类将防止出现同样的问题,因为它还会保留对活动的引用,从而导致内存泄漏。

答案 1 :(得分:3)

Android开发者页面提供了许多有用的示例:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

我认为您正在处理多个下载图像。但如果是这样,那么你的asyncTask应检查是否存在对imageView的引用。 你应该朝着这个方向前进:

public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {

        private final WeakReference<ImageView> imageViewReference;

        public ImageDownloader(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        protected void onPreExecute() {
            //Setup is done here
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            //this where i get the image using HttpURLConnection
        }

        protected void onProgressUpdate(Integer... params) {
            //Update a progress bar here, or ignore it, it's up to you
        }

        protected void onPostExecute(Bitmap bitmap) {

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

然后你打电话给例如:

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ImageView iv = (ImageView) findViewById(R.id.myImageView);
        new ImageDownloader(iv).execute("http://wanderingoak.net/bridge.png");
    }

答案 2 :(得分:1)

您需要将imageview声明为活动中的字段

在创建

上初始化它
private ImageView image_view;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    image_view = (ImageView) findViewById(R.id.remote_image);
    ImageDownloader download = new ImageDownloader();
    download.execute("http://wanderingoak.net/bridge.png");
}

您的异步任务:

public class ImageDownloader
    extends AsyncTask<String, Integer, Bitmap> {

    protected void onPreExecute(){
        //Setup is done here
    }

    @Override
    protected Bitmap doInBackground(String... params) {
        //this where i get the image using HttpURLConnection 
    }

    protected void onProgressUpdate(Integer... params){
        //Update a progress bar here, or ignore it, it's up to you
    }

    protected void onPostExecute(Bitmap img){
        if(image_view!=null && img!=null){
            image_view.setImageBitmap(img);
        }
    }