You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio使用Retrofit+Gson时ImageView无法加载URL图片求助

问题排查与修复方案
  • 核心问题:子线程直接操作UI。安卓系统禁止非主线程更新View组件,你在自定义的工作线程中直接调用setImageBitmap方法设置图片,属于非法操作,不会生效甚至会触发崩溃。
  • 复用错位问题:RecyclerView的item会被复用,每次onBindViewHolder都开启新线程加载图片,没有绑定当前item的位置,滑动时会出现图片串位的问题。
  • 资源泄漏问题:加载图片的InputStream使用后未主动关闭,会造成内存泄漏;未做图片缓存,滑动时重复请求网络,性能差。
  • 潜在解析问题:如果Photo类的字段名和接口返回的字段不完全匹配,Gson会解析出空值,导致图片链接无效。
修复步骤

1. 替换线程逻辑,切主线程更新UI

把onBindViewHolder中的线程逻辑替换为AsyncTask实现,自动切主线程更新,同时增加位置校验避免错位:

@Override
public void onBindViewHolder(RecyclerViewHolder holder, @SuppressLint("RecyclerView") int position) {
    holder.title.setText(photos.get(position).title);
    holder.albumid.setText(photos.get(position).albumId);
    holder.regid.setText(photos.get(position).id);
    
    // 先设置占位图,避免显示复用的旧图片,换成你自己项目里的占位资源即可
    holder.circleImageView.setImageResource(R.drawable.ic_placeholder);
    holder.imageView.setImageResource(R.drawable.ic_placeholder);

    String thumbUrl = photos.get(position).thumbnailUrl;
    String imgUrl = photos.get(position).url;

    new AsyncTask<Void, Void, Bitmap[]>() {
        @Override
        protected Bitmap[] doInBackground(Void... voids) {
            Bitmap thumbBitmap = getBitmapFromURL(thumbUrl);
            Bitmap imgBitmap = getBitmapFromURL(imgUrl);
            return new Bitmap[]{thumbBitmap, imgBitmap};
        }

        @Override
        protected void onPostExecute(Bitmap[] bitmaps) {
            // 校验当前holder的位置是否匹配,避免滑动时图片错位
            if (holder.getAdapterPosition() != position) return;
            if (bitmaps[0] != null) {
                holder.circleImageView.setImageBitmap(bitmaps[0]);
            }
            if (bitmaps[1] != null) {
                holder.imageView.setImageBitmap(bitmaps[1]);
            }
        }
    }.execute();
}

2. 优化图片加载方法,关闭输入流

修改getBitmapFromURL方法,主动关闭资源避免内存泄漏:

public static Bitmap getBitmapFromURL(String src) {
    HttpURLConnection connection = null;
    InputStream input = null;
    try {
        Log.e("src",src);
        URL url = new URL(src);
        connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        input = connection.getInputStream();
        return BitmapFactory.decodeStream(input);
    } catch (IOException e) {
        e.printStackTrace();
        Log.e("Exception",e.getMessage());
        return null;
    } finally {
        // 主动关闭资源
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            connection.disconnect();
        }
    }
}

3. 其他检查项

  • 检查Photo类的字段名是否和接口返回一致,比如thumbnailUrl、url字段大小写、拼写完全匹配,否则Gson会解析为空。
  • 如果你用的是http的图片链接,Android 9及以上默认禁止明文传输,需要在AndroidManifest.xml的application标签中增加android:usesCleartextTraffic="true"配置,或者把图片链接换成https。
  • ApiInterface中的@GET("/photos")可以去掉开头的斜杠,改为@GET("photos"),避免路径拼接出错。

内容的提问来源于stack exchange,提问作者Jessica Almany

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 22:36:02