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

如何在RecyclerView中加载URL图片并解决Network Thread异常问题

问题原因

你遇到的Network Thread异常是因为Android系统禁止在**主线程(UI线程)**执行网络请求,onBindViewHolder方法运行在主线程,你直接在其中发起HttpURLConnection请求自然会触发报错。除此之外你的代码还存在图片列表下标越界、无缓存、列表复用错位等潜在问题。

最优方案:使用成熟图片加载框架

强烈建议直接使用第三方图片加载库,一行代码即可完成需求,库会自动处理线程调度、内存/磁盘缓存、列表滑动复用错位、OOM规避、加载状态占位等问题,不需要你手动写复杂的网络加载逻辑。
以Glide为例,替换原有加载图片的全部代码即可:

// 注意你原有代码getImages().get(position)是错误写法:每个专辑的图片列表一般只有3个不同尺寸,列表position超过3就会越界,应取对应尺寸的下标,比如取第0个大图或者第2个缩略图
String imageUrl = model.getTrack().getAlbum().getImages().get(0).getUrl();
Glide.with(context)
    .load(imageUrl)
    // 可选:设置加载中的占位图
    .placeholder(R.drawable.placeholder_cover)
    // 可选:设置加载失败的占位图
    .error(R.drawable.error_cover)
    .into(holder.songCover);
原有代码修复方案

如果你坚持要自己实现图片加载逻辑,需要把网络请求放到子线程执行,完成后切回主线程设置图片,同时要处理列表复用错位问题:

@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    ItemPayload model = list.get(position);
    Log.d("aaa",model.getTrack().getName().toString());
    // 先给ImageView设置tag,防止复用错位
    String image = model.getTrack().getAlbum().getImages().get(0).getUrl();
    holder.songCover.setTag(image);
    // 子线程加载图片
    new Thread(() -> {
        Bitmap mIcon_val = null;
        try {
            URL newurl = new URL(image);
            HttpURLConnection conn= (HttpURLConnection)newurl.openConnection();
            conn.setDoInput(true);
            conn.connect();
            InputStream is = conn.getInputStream();
            mIcon_val = BitmapFactory.decodeStream(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 切回主线程设置图片
        Bitmap finalMIcon_val = mIcon_val;
        ((Activity)context).runOnUiThread(() -> {
            // 比对tag,避免复用错位
            if (holder.songCover.getTag().equals(image) && finalMIcon_val != null) {
                holder.songCover.setImageBitmap(finalMIcon_val);
            }
        });
    }).start();

    // 后续原有逻辑不变
    holder.textSong.setText(model.getTrack().getName());
    holder.textArtist.setText(model.getTrack().getArtists().get(0).getName());
    holder.textTrack.setText(model.getTrack().getAlbum().getTotal_tracks().toString());
    String url = model.getTrack().getExternal_urls().getSpotify();
    holder.textSong.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent viewIntent =
                    new Intent("android.intent.action.VIEW", Uri.parse(url));
            viewIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.startActivity(viewIntent);
        }
    });
}

注意:自行实现的方案仍缺少缓存、OOM处理、加载状态等能力,仅作为原理参考,生产环境优先使用成熟框架。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 18:36:02