如何从 onResponse 返回值 [英] How do I return a value from onResponse

查看:53
本文介绍了如何从 onResponse 返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上这是代码结构,我想知道如何修改我的代码,以便我可以在 onResponse 中获取值并返回它.截至目前,我的 mainReply 变量返回(空白)",但我希望它在我的 onResponse 段内传递名为 details 的数组列表中的数据.请放心,我已经检查过返回值,但我无法从 onResponse 段中获取要传递的值.

Basically this it the code structure, I would like to know how i can modify my codes so that I can get the value inside onResponse and returning it. As of now, my mainReply variable return "(blank)" but im expecting it to pass the data in the arraylist called details inside my onResponse segment. Rest assure, there are values returned as I have checked, but i just cant get the value to be passed out of the onResponse segment.

我已经检查了替代方案,他们提到使用接口.但是,我不知道如何修改我的代码以使用提到接口和使用回调的解决方案.

I have checked for alternatives and they mentioned to use interface. However, I do not know how to modify my codes to use the solution that mentioned interface and use of callBacks.

public class MainActivity extends AppCompatActivity {

    EditText et_message;
    FloatingActionButton fab_send;
    API api;
    ListView list_view_conversation;
    List<ChatModel> list_chat = new ArrayList<>();
    RevealDetailsCallbacks callback;

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

        et_message = (EditText) findViewById(R.id.et_message);
        fab_send = (FloatingActionButton) findViewById(R.id.fab_send);
        list_view_conversation = (ListView) findViewById(R.id.list_view_conversation);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        api = retrofit.create(API.class);

        fab_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //this method ultimately is to get response and send back to user
                String s = et_message.getText().toString();
                ChatModel model = new ChatModel(s, true);
                list_chat.add(model);
                new retrieveDetails().execute(list_chat);

                et_message.setText("'");
            }
        });

    }

    public class retrieveDetails extends AsyncTask<List<ChatModel>, Void, String> {
        String text = et_message.getText().toString();
        String mainReply = "";
        List<ChatModel> models;
        List<String> details = new ArrayList<String>();

        @Override
        public String doInBackground(List<ChatModel>[] lists) {
            Call<List<Patient>> call = api.getPatients();
            models = lists[0];
            call.enqueue(new Callback<List<Patient>>() {
                public String reply;

                @Override
                public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
                    List<Patient> patients = response.body();

                    for (int i = 0; i < patients.size(); i++) {
                        if (patients.get(i).getNric().equals(text)) {
                            details.add("Name: " + patients.get(i).getName() + "\nNRIC: " + patients.get(i).getNric()
                                    + "\nDOB: " + patients.get(i).getDob() + "\nContact No: " + patients.get(i).getContactno());
                        }
                    }
                    this.mainReply = details.get(0);
                    Log.i("Here Log i", reply);
                }

                @Override
                public void onFailure(Call<List<Patient>> call, Throwable t) {
                    Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
            return mainReply;//I want to reply with the data added into the details arraylist in the onResponse segment
        }


        @Override
        public void onPostExecute(String s) {
            ChatModel chatModel = new ChatModel(s, false);
            models.add(chatModel);
            CustomAdapter adapter = new CustomAdapter(models, getApplicationContext());
            list_view_conversation.setAdapter(adapter);
        }
    }


}

推荐答案

如果你想修改你现有的代码,你可以添加一个类似于我在上面添加的接口 (RevealDetailsCallbacks),将它传递给 asynctask 构造函数,然后运行.代码如下所示:

If you wanted to modify your existing code, you would add an interface like the one I added up top (RevealDetailsCallbacks), pass it into the asynctask constructor, and run it. The code would look like this:

public class MainActivity extends AppCompatActivity {

    //Interface callback here
    interface RevealDetailsCallbacks {
        public void getDataFromResult(List<String> details);
    }

    EditText et_message;
    FloatingActionButton fab_send;
    API api;
    ListView list_view_conversation;
    List<ChatModel> list_chat = new ArrayList<>();
    RevealDetailsCallbacks callback;

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

        et_message = (EditText) findViewById(R.id.et_message);
        fab_send = (FloatingActionButton) findViewById(R.id.fab_send);
        list_view_conversation = (ListView) findViewById(R.id.list_view_conversation);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API.BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        this.callback = new RevealDetailsCallbacks() {
            @Override
            public void getDataFromResult(List<String> details) {
                //Do stuff here with the returned list of Strings
            }
        };

        api = retrofit.create(API.class);

        fab_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //this method ultimately is to get response and send back to user
                String s = et_message.getText().toString();
                ChatModel model = new ChatModel(s, true);
                list_chat.add(model);
                new retrieveDetails(callback).execute(list_chat);

                et_message.setText("'");
            }
        });

    }

    public class retrieveDetails extends AsyncTask<List<ChatModel>, Void, String> {
        String text = et_message.getText().toString();
        String mainReply = "";
        List<ChatModel> models;
        List<String> details = new ArrayList<String>();
        private RevealDetailsCallbacks listener;

        retrieveDetails(RevealDetailsCallbacks listener){
            this.listener = listener;
        }

        @Override
        public String doInBackground(final List<ChatModel>[] lists) {
            Call<List<Patient>> call = api.getPatients();
            models = lists[0];
            call.enqueue(new Callback<List<Patient>>() {
                public String reply;

                @Override
                public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
                    List<Patient> patients = response.body();

                    for (int i = 0; i < patients.size(); i++) {
                        if (patients.get(i).getNric().equals(text)) {
                            details.add("Name: " + patients.get(i).getName() + "\nNRIC: " + patients.get(i).getNric()
                                    + "\nDOB: " + patients.get(i).getDob() + "\nContact No: " + patients.get(i).getContactno());
                        }
                    }
                    this.mainReply = details.get(0);
                    Log.i("Here Log i", reply);
                    if(listener != null) {
                        listener.getDataFromResult(details);
                    }
                }

                @Override
                public void onFailure(Call<List<Patient>> call, Throwable t) {
                    //Don't make a toast here, it will throw an exception due to it being in doInBackground
                    //Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
                }
            });
            return mainReply;//I want to reply with the data added into the details arraylist in the onResponse segment
        }


        @Override
        public void onPostExecute(String s) {
            ChatModel chatModel = new ChatModel(s, false);
            models.add(chatModel);
            CustomAdapter adapter = new CustomAdapter(models, getApplicationContext());
            list_view_conversation.setAdapter(adapter);
        }
    }
}

但是,这里不需要 asynctask,因为您正在运行 Retrofit 并调用在后台线程上运行的 .enqueue.更简单的版本如下所示:

However, there is no need for asynctask here since you are running Retrofit and calling .enqueue, which runs on a background thread. A simpler version would look like this:

public class MainActivity extends AppCompatActivity {

    //Interface callback here
    interface RevealDetailsCallbacks {
        public void getDataFromResult(List<String> details);
    }

    //Keep your same variables here

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

        //Same setup here

        this.callback = new RevealDetailsCallbacks() {
            @Override
            public void getDataFromResult(List<String> details) {
                //Do stuff here with the returned list of Strings
            }
        };


        fab_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //Same setup here, then call the method
                makeWebCalls();
            }
        });

    }

    private void makeWebCalls(){
        Call<List<Patient>> call = api.getPatients();
        models = lists[0];
        call.enqueue(new Callback<List<Patient>>() {
            @Override
            public void onResponse(Call<List<Patient>> call, Response<List<Patient>> response) {
                //Run your response code here. When done, pass to the callback
            }

            @Override
            public void onFailure(Call<List<Patient>> call, Throwable t) {
                Toast.makeText(getApplicationContext(), t.getMessage(), Toast.LENGTH_SHORT).show();
            }
        });
    }
}

这篇关于如何从 onResponse 返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆