Volley Request将之前的值设置为TextView

时间:2016-08-20 17:05:22

标签: android android-volley http-get

我试图了解如何在android中使用volley,所以在我的项目中我从http://uinames.com/api/?amount=1查询单个名称

在应用程序中,我有一个按钮,它调用函数来发出请求,然后将其设置为TextView。另外,对于调试目的,我正在记录来自url的响应。在按钮上单击响应在logcat中正确显示,但文本未设置为TextView,直到下次单击该按钮。

以下是JsonObjectRequest的代码

public String getName() {
        JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
                URL, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            full_name = response.getString(name) + " " + response.getString(last);
                            Log.d(TAG, full_name);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });
        AppController.getInstance().addToRequestQueue(objectRequest, "");

        return full_name;
    } 

以下是MainActivity中调用方法getName()

的代码
mButton = (Button) findViewById(R.id.btn);
        mTextView = (TextView) findViewById(R.id.text);

        final RequestClass newReq = new RequestClass();

        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                name = newReq.getName();
                mTextView.setText(name);
            }
        });

3 个答案:

答案 0 :(得分:1)

以下是调用函数String getName()时会发生的情况:

  1. 构造JsonObjectRequest,并将响应和错误侦听器传递给请求。请注意,在相应事件发生之前,侦听器不会执行。
  2. JsonObjectRequest被添加到请求队列中,当线程池中的线程可用时执行。
  3. 到目前为止,尚未触及full_name变量,并且您返回分配给它的最后一个值(这就是为什么当您再次单击该按钮时,您会在文本视图中获得一个名称)。
  4. 您的请求获得响应,并且在您的函数返回后,调用侦听器为full_name分配新值。这是您下次调用getName()时获得的值。 。
  5. 通常,像getName这样的函数无法执行网络操作并立即返回其结果。它需要阻止直到它有来自服务器的响应(这在android中是prohibited)。或者,它可以在没有获取结果的情况下返回,并且具有一个回调函数(或一个监听器),当它可用时调用结果(这是Volley库中的一般方法)。

    这意味着您必须在响应侦听器中setText。我注意到你的网络请求RequestClass有一个单独的类,为了保持你的设计原样,一个解决方案就是将监听器传递给getName()函数(以及所有其他做网络的函数)在这个类中的东西),它可能看起来像这样:

    public void getName(Response.Listener<JSONObject> responseListener,
                        Response.ErrorListener errorListener) {
        JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
                URL, null, responseListener, errorListener);
        AppController.getInstance().addToRequestQueue(objectRequest, "");
    }
    

    在你的活动中,你必须传递这样的听众:

    mButton.setOnClickListener(new View.OnClickListener() {
        @Override 
        public void onClick(View view) {
            name = newReq.getName(
                    new Response.Listener<JSONObject>() {
                        @Override 
                        public void onResponse(JSONObject response) {
                            try {
                                String full_name = response.getString("name") + " " + response.getString("last");
                                mTextView.setText(full_name);
                                Log.d(TAG, full_name);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }, 
                    new Response.ErrorListener() {
                        @Override 
                        public void onErrorResponse(VolleyError error) {
                        }
                    });
        }
    
    });
    

    作为更好的设计,您可能希望避免从活动中传递Volley个侦听器(不必了解volley),因此您可能希望定义自己的侦听器接口,覆盖并将其从活动传递到您的网络类(您实例化Response.ListenerResponse.ErrorListener并覆盖它们以调用侦听器中的函数。)

答案 1 :(得分:0)

Volley库已被弃用,因此请勿使用Volley库。

Volley的最佳替代品是RetroFit库。

答案 2 :(得分:0)

试试这个

public void getName() {
        JsonObjectRequest objectRequest = new JsonObjectRequest(Request.Method.GET,
                URL, null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            full_name = response.getString("name") + " " + response.getString("last");

                            runOnUiThread(new Runnable() {
    @Override
    public void run() {
       //Your code to run in GUI thread here
        mTextView.setText(full_name);
    }
    });
                            Log.d(TAG, full_name);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {

                    }
                });
        AppController.getInstance().addToRequestQueue(objectRequest, "");


    } 




mButton = (Button) findViewById(R.id.btn);
        mTextView = (TextView) findViewById(R.id.text);



        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getName();

            }
        });
相关问题