无法从URL加载图像

5

我尝试从URL加载图像,但是它没有起作用。发生了两个不同的错误。当我输入以www开头的URL时,应用程序不会关闭,但也不会加载图像,只会显示一个白色空间。但是如果URL以http://开头,则应用程序会关闭。

我正在使用的代码来加载图像如下:

public class ThreadAdapter extends BaseAdapter {
    ArrayList<Threadx> data;
    LayoutInflater inflater;
    public ThreadAdapter(Context context, ArrayList<Threadx> data) {
        super();
        inflater = LayoutInflater.from(context);
        this.data = data;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }
    private static class ViewHolder {
        TextView tvSubject;
        TextView tvContent;
        ImageView imagen;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_row_thread, null);
            viewHolder = new ViewHolder();
            viewHolder.tvSubject = (TextView) convertView
                    .findViewById(R.id.tvSubject);
            viewHolder.tvContent = (TextView) convertView
                    .findViewById(R.id.tvContent);
            viewHolder.imagen = (ImageView) convertView
                    .findViewById(R.id.image);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        String subject = data.get(position).getSubject();
        String content = data.get(position).getContent();
        String imagen = data.get(position).getImagen();
        viewHolder.tvSubject.setText(subject);
        viewHolder.tvContent.setText(content);
        Bitmap bitmap = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL("www.matrallune.com/images/imagen_corporativa.jpg");
            //bitmap = BitmapFactory.decodeStream((InputStream)new URL("www.matrallune.com/images/imagen_corporativa.jpg").getContent());
            //bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
            urlConnection = (HttpURLConnection) url.openConnection();
            InputStream is = urlConnection.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        viewHolder.imagen.setImageBitmap(bitmap);
        return convertView;
    }
}

我尝试了不同的方法,正如您在代码中所看到的,但所有方法都存在相同的问题。我的意图是从变量“imagen”中捕获URL。


你漏掉了 urlConnection.connect(); - Krupal Shah
你的应用程序是否拥有正确的权限?你是否遇到了异常? - G B
1
你也可以使用图片加载库Picasso,它可以高效地加载图片,并可以缓存响应。http://square.github.io/picasso/ - theapache64
1
我建议始终在URL开头添加协议。 - kamilmasta
@Krupal 我尝试了,但它没有改变任何东西。 - Manel Mendez
显示剩余5条评论
4个回答

3

使用这个问题 >> 在安卓中从URL加载Bitmap到ImageView

public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
    private ImageView imageView;
    private Bitmap image;

    public DownloadImageTask(ImageView imageView) {
        this.imageView = imageView;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            image = BitmapFactory.decodeStream(in);
        } catch (Exception e) {
            image = null;
        }
        return image;
    }

    @SuppressLint("NewApi")
    protected void onPostExecute(Bitmap result) {
        if (result != null) {
            imageView.setImageBitmap(result);
        }
    }
}

现在在你的代码中调用它:
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder = null;
    if (convertView == null) {
        conv`enter code here`ertView = inflater.inflate(R.layout.list_row_thread, null);
        viewHolder = new ViewHolder();
        viewHolder.tvSubject = (TextView) convertView
                .findViewById(R.id.tvSubject);
        viewHolder.tvContent = (TextView) convertView
                .findViewById(R.id.tvContent);
        viewHolder.imagen = (ImageView) convertView
                .findViewById(R.id.image);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    String subject = data.get(position).getSubject();
    String content = data.get(position).getContent();
    String imagen = data.get(position).getImagen();
    viewHolder.tvSubject.setText(subject);
    viewHolder.tvContent.setText(content);
    new DownloadImageTask(viewHolder.imagen).execute("www.matrallune.com/images/imagen_corporativa.jpg");
    return convertView;
}

哇,它能工作了!这是因为 AsyncTask 的缘故吗?感谢您的帮助! - Manel Mendez
你不能在工作线程中更新UI。因此,异步任务很适合这样做。 - Maycon Cardoso
谢谢提供的信息 ;) - Manel Mendez

1
我猜您可能遗漏了 urlConnection.connect();
请将您的代码改为:
    try {
            URL url = new URL("www.matrallune.com/images/imagen_corporativa.jpg");
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();
            InputStream is = urlConnection.getInputStream();
            bitmap = BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

不确定。

如评论中所建议,最好使用类库Picasso。它非常容易。只需集成并更改代码为:

Picasso.with(context).load(url).into(imgView);

更新: 尝试包含 connection.setDoInput(true); setUseCaches(false)


@ManelMendez 好的,我只是猜测而已...可能还有其他问题。 - Krupal Shah
始终得到相同的结果。 - Manel Mendez

1
通过Picasso加载图像就像说123一样简单,您就完成了。
Picasso
.with(context) //Context 
.load("http://i.imgur.com/DvpvklR.png") //Can be Url,File..
.into(imageView)//The ImageView;

这只是普通的加载,您可以在文档中找到更多选项。
根据您的代码。
Picasso
    .with(context) //Context 
    .load("http://matrallune.com/images/imagen_corporativa.jpg") //Can be Url,File..
    .into(viewHolder.imagen)//The ImageView;

你只是想用上述代码替换图像加载代码。 你的最终适配器
public class ThreadAdapter extends BaseAdapter {
    ArrayList<Threadx> data;
    LayoutInflater inflater;
    private Context mContext;

    public ThreadAdapter(Context mContext, ArrayList<Threadx> data) {
        super();
        inflater = LayoutInflater.from(context);
        this.data = data;
        this.mContext = mContext;
    }

    @Override
    public int getCount() {
        return data.size();
    }

    @Override
    public Object getItem(int position) {
        return data.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    private static class ViewHolder {
        TextView tvSubject;
        TextView tvContent;
        ImageView imagen;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder = null;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.list_row_thread, null);
            viewHolder = new ViewHolder();
            viewHolder.tvSubject = (TextView) convertView
                    .findViewById(R.id.tvSubject);
            viewHolder.tvContent = (TextView) convertView
                    .findViewById(R.id.tvContent);
            viewHolder.imagen = (ImageView) convertView
                    .findViewById(R.id.image);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        String subject = data.get(position).getSubject();
        String content = data.get(position).getContent();
        String imagen = data.get(position).getImagen();
        viewHolder.tvSubject.setText(subject);
        viewHolder.tvContent.setText(content);

        //Loading image
        Picasso
        .with(mContext) //Context 
        .load("http://matrallune.com/images/imagen_corporativa.jpg") //Can be Url,File..
        .into(viewHolder.imagen)//The ImageView;


        return convertView;
    }
}

如果您正在从Fragment初始化适配器,则应将上下文作为getActivity()传递,或者您也可以在片段的onAttach()中进行初始化。
如果您正在从活动中初始化适配器,则只需传递this即可。
初始化
来自活动
ThreadAdapter tAdapter = new ThreadAdapter(this,data);

从Fragment

ThreadAdapter tAdapter = new ThreadAdapter(getActivity(),data);

@ManelMendez 更新了您的最终适配器,其中包含A-Z。如果需要更多澄清,请问我。 - theapache64
当我尝试使用代码(当我加入属性上下文)时,应用程序停止了。但是感谢帮助。 - Manel Mendez
展示一下Logcat在说什么。 - theapache64
看:05-13 19:12:20.285 10989-10989/api.dat.dsaqp1415gm2.dsa.eetac.upc.edu.dat_android E/AndroidRuntime:致命异常:主要 进程:api.dat.dsaqp1415gm2.dsa.eetac.upc.edu.dat_android,PID:10989 java.lang.IllegalArgumentException:上下文不能为空。 - Manel Mendez
好的,问题是您传递了一个 null Context。我能看一下您如何初始化 Adapter 对象吗? - theapache64
显示剩余2条评论

0

有点晚了 @ManelMendez 但它需要是mContext。 - Greg
让我们尝试使用 ClassName.this。 - Nam Hoang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接