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

Android应用出现Choreographer丢帧警告、API请求响应慢该如何优化?

问题核心原因

你遇到的跳帧警告核心原因是耗时操作直接在主线程执行,具体问题点如下:

  • 网络请求、HTTP可达性检测都是耗时操作,你在getClassTeacherList()方法中直接在主线程调用isServerReachable()、serverAuthenticateService.getClassTeacherList()两个网络相关方法,直接阻塞主线程10s以上,才会出现跳几百帧的警告
  • 每次业务请求前额外多执行了一次服务器可达性HTTP请求,等于一次业务操作要跑两次网络,额外拉长了整体耗时
  • 仅在401刷新token逻辑里开了子线程,正常请求全部走主线程,没有统一的异步请求调度逻辑

具体优化方案

1. 所有网络操作移到子线程执行

Android要求所有网络、IO、复杂计算操作都不能在主线程执行,你可以直接修正请求逻辑,示例代码如下:

private void getClassTeacherList() {
    academicPeriod = (AcademicPeriod) mSpnPeriod.getItemAtPosition(keyPos);
    // 所有网络操作全部丢到子线程执行
    new Thread(() -> {
        // 仅做轻量的本地网络连通判断,不要做HTTP请求
        if (!isNetWorkAvailable(getApplicationContext())) {
            // 操作UI必须切回主线程
            runOnUiThread(() -> getMsgBox("No connection", "No connection"));
            return;
        }
        // 直接执行业务请求,不要额外做服务器可达检测
        classTeacherList = serverAuthenticateService.getClassTeacherList(selClass.getId(),academicPeriod.getId(), authtoken, getApplicationContext());
        if (AppBackupCache.checkToken == 200) {
            showClassTeacherList();
        } else if (AppBackupCache.checkToken == 401) {
            manager.invalidateAuthToken("com.lss.loop", authtoken);
            authtoken = null;
            final AccountManagerFuture<Bundle> future = manager.getAuthToken(mAccount, AccountGeneral.AUTHTOKEN_TYPE_FULL_ACCESS, new Bundle(), true, null, null);
            try {
                Bundle bnd = (Bundle) future.getResult();
                authtoken = bnd.getString("authtoken");
                if (authtoken != null) {
                    classTeacherList = serverAuthenticateService.getClassTeacherList(selClass.getId(),academicPeriod.getId(), authtoken, getApplicationContext());
                    if (AppBackupCache.checkToken == 200) {
                        showClassTeacherList();
                        return;
                    } else {
                        runOnUiThread(() -> getMsgBox("Error", "Something went wrong"));
                        return;
                    }
                }
                runOnUiThread(() -> getMsgBox("", "Token not refreshed...."));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        AppBackupCache.checkToken = 401;
    }).start();
}

// 仅做轻量的本地网络状态判断,不要发起HTTP请求
public boolean isNetWorkAvailable(Context applicationContext) {
    ConnectivityManager connMan = (ConnectivityManager) applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo netInfo = connMan.getActiveNetworkInfo();
    return netInfo != null && netInfo.isConnected();
}

2. 移除冗余的服务器可达性检测

你当前的逻辑等于每次业务请求都要先发起一次HTTP请求验证服务器是否可达,耗时直接翻倍,完全没有必要:

  • 只需要用ConnectivityManager判断本地网络是否连通即可
  • 业务请求本身如果超时、失败,直接弹出对应错误提示即可,不需要提前做可达性校验

3. 优化网络请求框架

你当前使用的RestTemplate同步请求适配性很差,推荐换成移动端专用的网络方案:

  • 换成OkHttp+Retrofit的组合,原生支持异步请求,自动调度线程,不需要手动维护子线程
  • 开启网络缓存,相同参数的请求可以直接读取本地缓存,不需要每次都发起服务器请求,大幅提升响应速度
  • 统一封装token过期刷新逻辑,不需要每个接口单独写401处理代码,减少重复逻辑

4. 其他细节优化

  • 单选按钮切换时,先取消上一个未完成的请求,避免多个请求并行占用资源
  • 列表Adapter不要每次请求成功都重新创建,只更新数据集后调用notifyDataSetChanged()即可,减少UI创建耗时
  • 优化RecyclerView布局,开启Item缓存,减少列表渲染的耗时

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 17:06:00