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

如何在AsyncHttpClient(loopj)的onSuccess外部使用获取的JSON数据?

问题:如何在AsyncHttpClient的onSuccess外部使用异步获取的数据?

我当前使用loopj的Android异步框架AsyncHttpClient读取JSON数据,代码如下:

public class HorariosActivity extends AppCompatActivity { 
    String hora_inicio; 
    String hora_fin; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_horarios); 
        obtDatosBD(); 
        // 这里想使用hora_inicio和hora_fin,但拿不到值
    } 
    private void obtDatosBD(){ 
        final AsyncHttpClient client = new AsyncHttpClient(); 
        client.get("http://192.168.0.26/WS_policlinica/horas.php", new AsyncHttpResponseHandler() { 
            @Override 
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
                if(statusCode==200){ 
                    try { 
                        JSONArray jsonArray = new JSONArray(new String(responseBody)); 
                        for (int i=0; i<jsonArray.length(); i++){ 
                            hora_inicio = jsonArray.getJSONObject(i).getString("FISIO_HORA_INICIO"); 
                            hora_fin = jsonArray.getJSONObject(i).getString("FISIO_HORA_FIN"); 
                        } 
                    }catch (Exception e){ 
                        e.printStackTrace(); 
                    } 
                } 
            } 
            @Override 
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
            } 
        }); 
    }
}

我可以在onSuccess方法中接收并存储hora_inicio和hora_fin数据,但不知如何在onSuccess方法外部使用这些值,尤其想在onCreate中使用却无法实现,求解决方法。


解决方案

这个问题其实是异步编程里的典型坑——AsyncHttpClient的网络请求是异步执行的,也就是说你在onCreate里调用obtDatosBD()之后,代码会立刻继续往下跑,根本不会等网络请求返回结果。等onSuccess回调触发、你把数据存到hora_inicio和hora_fin里的时候,onCreate早就执行完了,这时候你再去拿这两个值自然是空的。

下面给你几种实用的解决办法:

方法一:在onSuccess里直接调用处理数据的方法

最简单直接的方式,就是把需要使用数据的逻辑封装成独立方法,在onSuccess拿到数据后立刻调用它。比如:

public class HorariosActivity extends AppCompatActivity { 
    String hora_inicio; 
    String hora_fin; 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_horarios); 
        obtDatosBD(); 
    } 

    private void obtDatosBD(){ 
        final AsyncHttpClient client = new AsyncHttpClient(); 
        client.get("http://192.168.0.26/WS_policlinica/horas.php", new AsyncHttpResponseHandler() { 
            @Override 
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
                if(statusCode==200){ 
                    try { 
                        JSONArray jsonArray = new JSONArray(new String(responseBody)); 
                        for (int i=0; i<jsonArray.length(); i++){ 
                            hora_inicio = jsonArray.getJSONObject(i).getString("FISIO_HORA_INICIO"); 
                            hora_fin = jsonArray.getJSONObject(i).getString("FISIO_HORA_FIN"); 
                        } 
                        // 拿到数据后直接调用处理方法
                        useHorarioData();
                    }catch (Exception e){ 
                        e.printStackTrace(); 
                    } 
                } 
            } 

            @Override 
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
                Toast.makeText(HorariosActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show();
            } 
        }); 
    }

    // 专门处理时间数据的方法
    private void useHorarioData(){
        // 这里可以正常使用hora_inicio和hora_fin,比如更新UI
        // TextView tvInicio = findViewById(R.id.tv_hora_inicio);
        // tvInicio.setText("开始时间:" + hora_inicio);
        // TextView tvFin = findViewById(R.id.tv_hora_fin);
        // tvFin.setText("结束时间:" + hora_fin);
        Toast.makeText(this, "开始时间:" + hora_inicio + " | 结束时间:" + hora_fin, Toast.LENGTH_SHORT).show();
    }
}

方法二:自定义回调接口

如果你的数据处理逻辑需要复用,或者要在多个地方使用,可以自定义一个回调接口,把数据传递到需要的地方:

public class HorariosActivity extends AppCompatActivity { 
    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_horarios); 
        // 调用请求方法时传入回调
        obtDatosBD(new HorarioCallback() {
            @Override
            public void onHorarioLoaded(String inicio, String fin) {
                // 在这里拿到数据并使用
                Toast.makeText(HorariosActivity.this, "开始时间:" + inicio + " | 结束时间:" + fin, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLoadFailed() {
                Toast.makeText(HorariosActivity.this, "加载失败,请重试", Toast.LENGTH_SHORT).show();
            }
        }); 
    } 

    // 把回调接口作为参数传入请求方法
    private void obtDatosBD(final HorarioCallback callback){ 
        final AsyncHttpClient client = new AsyncHttpClient(); 
        client.get("http://192.168.0.26/WS_policlinica/horas.php", new AsyncHttpResponseHandler() { 
            @Override 
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
                if(statusCode==200){ 
                    try { 
                        JSONArray jsonArray = new JSONArray(new String(responseBody)); 
                        String hora_inicio = "";
                        String hora_fin = "";
                        for (int i=0; i<jsonArray.length(); i++){ 
                            hora_inicio = jsonArray.getJSONObject(i).getString("FISIO_HORA_INICIO"); 
                            hora_fin = jsonArray.getJSONObject(i).getString("FISIO_HORA_FIN"); 
                        } 
                        // 回调成功方法,传递数据
                        callback.onHorarioLoaded(hora_inicio, hora_fin);
                    }catch (Exception e){ 
                        e.printStackTrace(); 
                        callback.onLoadFailed();
                    } 
                } 
            } 

            @Override 
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
                callback.onLoadFailed();
            } 
        }); 
    }

    // 自定义回调接口
    interface HorarioCallback{
        void onHorarioLoaded(String horaInicio, String horaFin);
        void onLoadFailed();
    }
}

方法三:使用LiveData(推荐,适配Jetpack架构)

如果你在用Android Jetpack,用LiveData来观察数据变化会更符合现代Android开发规范,还能自动处理生命周期:

首先确保build.gradle里添加了LiveData依赖:

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.6.2"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.2"

然后修改代码:

import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

public class HorariosActivity extends AppCompatActivity { 
    // 创建LiveData对象保存时间数据
    private MutableLiveData<Horario> horarioLiveData = new MutableLiveData<>();

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.activity_horarios); 

        // 观察LiveData的数据变化,自动感知生命周期
        horarioLiveData.observe(this, new Observer<Horario>() {
            @Override
            public void onChanged(Horario horario) {
                // 数据更新时触发这里,直接使用数据
                Toast.makeText(HorariosActivity.this, "开始时间:" + horario.getHoraInicio() + " | 结束时间:" + horario.getHoraFin(), Toast.LENGTH_SHORT).show();
            }
        });

        obtDatosBD(); 
    } 

    private void obtDatosBD(){ 
        final AsyncHttpClient client = new AsyncHttpClient(); 
        client.get("http://192.168.0.26/WS_policlinica/horas.php", new AsyncHttpResponseHandler() { 
            @Override 
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { 
                if(statusCode==200){ 
                    try { 
                        JSONArray jsonArray = new JSONArray(new String(responseBody)); 
                        String hora_inicio = "";
                        String hora_fin = "";
                        for (int i=0; i<jsonArray.length(); i++){ 
                            hora_inicio = jsonArray.getJSONObject(i).getString("FISIO_HORA_INICIO"); 
                            hora_fin = jsonArray.getJSONObject(i).getString("FISIO_HORA_FIN"); 
                        } 
                        // 更新LiveData的数据
                        horarioLiveData.setValue(new Horario(hora_inicio, hora_fin));
                    }catch (Exception e){ 
                        e.printStackTrace(); 
                    } 
                } 
            } 

            @Override 
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { 
                Toast.makeText(HorariosActivity.this, "网络请求失败", Toast.LENGTH_SHORT).show();
            } 
        }); 
    }

    // 封装时间数据的实体类
    static class Horario{
        private String horaInicio;
        private String horaFin;

        public Horario(String horaInicio, String horaFin) {
            this.horaInicio = horaInicio;
            this.horaFin = horaFin;
        }

        public String getHoraInicio() {
            return horaInicio;
        }

        public String getHoraFin() {
            return horaFin;
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:04:26