Android使用OkHttp发起GET请求调用API无法在回调外获取listBeacons问题咨询
问题排查与解决方案
一、OkHttp请求突然失效的排查步骤
- 检查明文请求权限:安卓9(API 28)及以上系统默认禁止HTTP明文请求,你使用的是
http://开头的本地地址,需要在AndroidManifest.xml的application节点添加android:usesCleartextTraffic="true"配置,或者给本地API服务配置HTTPS证书。 - 验证网络连通性:确认APP运行设备和API服务所在设备处于同一局域网,没有子网隔离、防火墙拦截44374端口的情况,可直接在设备浏览器访问API地址验证能否正常返回数据。
- 排查序列化异常:你贴出的返回示例是单个JSON对象结构,但代码中使用
TypeReference<List<Beacon>>解析列表结构,如果API调整过返回格式,会直接抛出序列化异常终止后续逻辑,建议先打印myResponse完整内容,确认返回是数组还是单个对象,对应调整解析类型。 - 检查依赖变更:如果近期升级过OkHttp、Jackson相关依赖,可排查是否存在API兼容性变更,也可以添加OkHttp日志拦截器打印完整请求、响应信息定位具体错误。
二、将回调数据对外暴露的实现方案
OkHttp的enqueue是异步回调逻辑,不能直接给全局变量赋值后在主线程同步读取,推荐用接口回调的方式传递数据,需要跨组件使用时可配合全局单例、ViewModel实现:
第一步:定义回调接口
public interface BeaconCallback { void onBeaconsLoaded(List<Beacon> beacons); void onLoadFailed(Exception e); }
第二步:封装请求方法
public void loadBeacons(BeaconCallback callback) { OkHttpClient client = new OkHttpClient(); String url = "http://192.168.1.95:44374/api/beacons"; Request request = new Request.Builder().url(url).build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 切主线程回调避免UI操作报错 new Handler(Looper.getMainLooper()).post(() -> callback.onLoadFailed(e)); } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()){ String myResponse = response.body().string(); // 确认返回结构后调整解析逻辑,这里以返回列表为例 List<Beacon> listBeacons = objectMapper.readValue(myResponse, new TypeReference<List<Beacon>>(){}); new Handler(Looper.getMainLooper()).post(() -> callback.onBeaconsLoaded(listBeacons)); } else { new Handler(Looper.getMainLooper()).post(() -> callback.onLoadFailed(new RuntimeException("请求异常,响应码:" + response.code())) ); } } }); }
第三步:调用获取数据
// 在需要使用数据的位置调用 loadBeacons(new BeaconCallback() { @Override public void onBeaconsLoaded(List<Beacon> beacons) { // 此处拿到的beacons可直接传递给其他类、存入全局单例或者执行后续业务逻辑 } @Override public void onLoadFailed(Exception e) { e.printStackTrace(); // 自定义错误处理逻辑 } });
内容的提问来源于stack exchange,提问作者Tiago Pinto
相关产品推荐
相关产品推荐

