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

使用Executors替代AsyncTask加载网络图片到ImageView时应用崩溃

问题根源与修复方案

核心问题

错误日志中的NetworkOnMainThreadException是崩溃的直接原因——你在主线程(按钮点击事件属于主线程)直接调用了mImageLoadTask.call(),而call()方法包含网络请求操作,Android禁止在主线程执行耗时网络任务,因此触发崩溃。

另外你的SendtoserverActivity中mContext未初始化,getContext()会返回null,后续加载错误占位图时也会引发异常。

修复步骤

1. 初始化Activity的Context

在Sendtoserver的onCreate方法中添加Context初始化代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_sendtoserver);
    mContext = this; // 初始化Context
    // 其余原有代码...
}

2. 用TaskRunner异步执行任务

不要直接调用call(),而是通过你实现的TaskRunner类将网络请求放到子线程执行,在回调中更新UI。修改按钮点击事件代码:

getfromurlbtn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        TaskRunner taskRunner = new TaskRunner();
        taskRunner.executeAsync(mImageLoadTask, new TaskRunner.Callback<Bitmap>() {
            @Override
            public void onComplete(Bitmap result) {
                mImgfromurl.setImageBitmap(result);
            }
        });
    }
});

3. 优化资源释放(可选)

在ImageLoadTask的call()方法中添加资源关闭逻辑,避免内存泄漏:

@Override
public Bitmap call() {
    HttpURLConnection connection = null;
    InputStream input = null;
    try {
        URL urlConnection = new URL(url);
        connection = (HttpURLConnection) urlConnection.openConnection();
        connection.setDoInput(true);
        connection.connect();
        input = connection.getInputStream();
        return BitmapFactory.decodeStream(input);
    } catch (IOException exception) {
        return BitmapFactory.decodeResource(mContex.getResources(), R.drawable.ee);
    } finally {
        // 关闭资源
        if (input != null) {
            try {
                input.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            connection.disconnect();
        }
    }
}

修复原理

  • TaskRunner的executeAsync方法通过线程池将Callable的执行逻辑放到子线程,避免主线程被耗时网络操作阻塞。
  • 任务执行完成后,通过Handler切换回主线程更新UI,符合Android线程模型的要求(UI操作必须在主线程执行)。

内容的提问来源于stack exchange,提问作者eag-ehsan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:22