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

不使用Glide等第三方库 通过URL加载图片时Activity崩溃如何解决

问题根因
  • 核心错误是你把网络请求逻辑直接放在了onCreate方法中执行,Android 3.0及以上版本强制禁止在主线程执行网络操作,直接运行会抛出NetworkOnMainThreadException导致应用闪退。
  • 第二个错误是就算你绕过主线程网络限制,在子线程中直接调用setImageBitmap修改UI控件,也会触发UI操作线程异常,Android要求所有UI控件的修改必须在主线程执行。
  • 还有两处遗漏点:
    1. 没有在AndroidManifest.xml中声明网络访问权限,会导致网络请求被拦截。
    2. 没有对加载的图片做采样压缩,该原图分辨率很高,直接解码会占用大量内存,极易触发OOM(内存溢出)异常。
修复方案

步骤1:添加网络权限

在AndroidManifest.xml的manifest标签下添加权限声明:

<uses-permission android:name="android.permission.INTERNET" />

步骤2:调整图片加载逻辑

将网络请求放在子线程执行,加载完成后切换到主线程更新UI,同时添加图片压缩逻辑:

String imgUrl = "https://st3.depositphotos.com/1008939/12603/i/950/depositphotos_126032722-stock-photo-roaring-singing-woman.jpg";
ImageView img = findViewById(R.id.imageArtist);

// 启动子线程执行网络加载操作
new Thread(new Runnable() {
    @Override
    public void run() {
        Bitmap bitmap = null;
        InputStream input = null;
        try {
            // 第一次读取仅获取图片尺寸,不加载全图到内存
            input = new URL(imgUrl).openStream();
            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(input, null, options);
            input.close();

            // 计算采样率,按ImageView的170dp(约510px)压缩图片
            options.inSampleSize = calculateInSampleSize(options, 510, 510);
            options.inJustDecodeBounds = false;

            // 第二次读取加载压缩后的图片
            input = new URL(imgUrl).openStream();
            bitmap = BitmapFactory.decodeStream(input, null, options);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (input != null) {
                try {
                    input.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        // 切换到主线程更新ImageView
        Bitmap finalBitmap = bitmap;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (finalBitmap != null) {
                    img.setImageBitmap(finalBitmap);
                }
            }
        });
    }
}).start();

步骤3:添加图片采样率计算工具方法

private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
    int height = options.outHeight;
    int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
        int halfHeight = height / 2;
        int halfWidth = width / 2;
        // 采样率为2的指数,越高图片压缩比例越大
        while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) {
            inSampleSize *= 2;
        }
    }
    return inSampleSize;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 14:48:03