【问题标题】:How to get response from server?如何从服务器获得响应?
【发布时间】:2019-09-11 03:54:03
【问题描述】:

我正在编写一个请求休息 API(Yandex 磁盘)的类。我使用 volley,但我在获得响应方面确实存在一些问题。其余APIhere可以查看。

我使用 volley,我可以在调试器中得到响应,但在我的 Activity 中却没有。

这是我的Requests 课程

class Requests {
    private String response_of_server, token;
    private String url = "https://cloud-api.yandex.net/v1/disk";
    private Context context;

    Requests (String token, Context context) {
        this.token = token;
        this.context = context;
    }

    private void set_response_of_server(String response) {
        this.response_of_server = response;
    }

    String get_response() {
        return response_of_server;
    }

    void get_metadata_of_user() {

        try {
            /*Request*/

            RequestQueue queue = Volley.newRequestQueue(this.context);


            Response.ErrorListener error_listener = new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                }
            };
            Response.Listener<String> response_listener = new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response) {
                    set_response_of_server(response);
                }
            };

            StringRequest getRequest = new StringRequest(Request.Method.GET, url+"?fields=user", response_listener, error_listener) {
                @Override
                public Map<String, String> getHeaders() {
                    Map<String, String>  params = new HashMap<>();
                    params.put("Host", "cloud-api.yandex.net");
                    params.put("Authorization", token);
                    return params;
                }
            };
            queue.add(getRequest);
            /*Request end*/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

还有我想要回复的MainActivity

public class MainActivity extends AppCompatActivity {

    private final String ID_OF_APP = "Your token of app";
    private final String URL_FOR_CODE_QUERY = "https://oauth.yandex.com/authorize?response_type=token&client_id=" + ID_OF_APP;
    private String SAVED_TOKEN = "";

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

        Button btn_get_code = findViewById(R.id.btn_get_code); // send to get code page (yandex)
        btn_get_code.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                    Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(URL_FOR_CODE_QUERY));
                    startActivity(i);
            }
        });

        Button btn_sign_in = findViewById(R.id.btn_sign_in);
        btn_sign_in.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText code_field = findViewById(R.id.code_field);
                String token = code_field.getText().toString();
                save_token(token);
                try {
                    if(check_token()) {
                        //Toast.makeText(MainActivity.this, "You are successfully signed in", Toast.LENGTH_SHORT).show();
                        // TODO change activity
                    }
                    else {}
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //Toast.makeText(MainActivity.this, "Something went wrong. Please, check your connection and try again later", Toast.LENGTH_SHORT).show();
            }
        });
    }

    private void save_token(String token) {
        SharedPreferences sPref = getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor ed = sPref.edit();
        ed.putString(SAVED_TOKEN, token);
        ed.apply();
    }

    private String load_token() {
        SharedPreferences sPref = getPreferences(MODE_PRIVATE);
        return sPref.getString(SAVED_TOKEN, "");
    }

    private boolean check_token() throws InterruptedException {
        String token = load_token();
        String result;
        Requests request = new Requests(token, this);
        request.get_metadata_of_user();
        result = request.get_response();
        Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
        return !(result.equals("-1"));
    }
}

check_token() 函数此刻应该只是用服务器的响应来祝酒。但是,我无法从服务器获得 Toast 或任何响应。

【问题讨论】:

  • 请检查我的答案,如果可行,请告诉我。 :)

标签: java android android-asynctask android-volley


【解决方案1】:

您有一个Requests 类,它具有调用服务器API 的功能,即Asynchronous。因此,在 check_token() 函数中调用 request.get_metadata_of_user(); 后,您不会立即获得 result

因此,我建议您修改 Request 类,如下所示。

public class Requests {
    private String response_of_server, token;
    private String url = "https://cloud-api.yandex.net/v1/disk";
    private Context context;
    private HttpListener listener; // Add a listener to get the callback functionality

    Requests (String token, Context context, HttpListener listener) {
        this.token = token;
        this.context = context;
        this.listener = listener; // initialize the listener here
    }

    private void set_response_of_server(String response) {
        this.response_of_server = response;
        listener.onResponseReceived(response); // Send the response back to the calling class
    }

    String get_response() {
        return response_of_server;
    }

    void get_metadata_of_user() {

        try {
            RequestQueue queue = Volley.newRequestQueue(this.context);
            Response.ErrorListener error_listener = new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    error.printStackTrace();
                }
            };

            Response.Listener<String> response_listener = new Response.Listener<String>()
            {
                @Override
                public void onResponse(String response) {
                    set_response_of_server(response);
                }
            };

            StringRequest getRequest = new StringRequest(Request.Method.GET, url+"?fields=user", response_listener, error_listener) {
                @Override
                public Map<String, String> getHeaders() {
                    Map<String, String>  params = new HashMap<>();
                    params.put("Host", "cloud-api.yandex.net");
                    params.put("Authorization", token);
                    return params;
                }
            };

            queue.add(getRequest);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

现在HttpListener 类可能如下所示。创建HttpListener.java 并添加以下代码以将其创建为接口。

public interface HttpListener {
    public void onResponseReceived();
}

因此您需要在您的MainActivity 中实现此interface,如下所示。

public class MainActivity extends AppCompatActivity implements HttpListener {

    private final String ID_OF_APP = "Your token of app";

    // I fixed this part too. Please change if that is not useful
    private final String URL_FOR_CODE_QUERY = "https://oauth.yandex.com/authorize?response_type=" + SAVED_TOKEN + "&client_id=" + ID_OF_APP;
    private String SAVED_TOKEN = "";

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

        // ... I omitted some code

        Button btn_sign_in = findViewById(R.id.btn_sign_in);
        btn_sign_in.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                EditText code_field = findViewById(R.id.code_field);
                String token = code_field.getText().toString();
                save_token(token);

                try {
                    // if(check_token()) {
                        // The check_token function call is Async. This will not return immediately. Hence you might consider removing this if part. Simply just call the function and listen to the callback function when the response is received
                    // }

                    check_token(); // Simply call the function here
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    private void save_token(String token) {
        SharedPreferences sPref = getPreferences(MODE_PRIVATE);
        SharedPreferences.Editor ed = sPref.edit();
        ed.putString(SAVED_TOKEN, token);
        ed.apply();
    }

    private String load_token() {
        SharedPreferences sPref = getPreferences(MODE_PRIVATE);
        return sPref.getString(SAVED_TOKEN, "");
    }

    // I changed the return type as this is not returning anything.
    private void check_token() throws InterruptedException {
        String token = load_token();
        String result;
        Requests request = new Requests(token, this);
        request.get_metadata_of_user();

        // You will not get the response immediately here. So omit these codes.
        // result = request.get_response();
        // Toast.makeText(MainActivity.this, result, Toast.LENGTH_SHORT).show();
        // return !(result.equals("-1"));
    }

    @Override
    public void onResponseReceived(String response) {
        // Here is your response. Now you can use your response
        // and can perform the next action here. 
    }
}

请注意,代码未经测试。请根据您的要求进行修改。我希望这可以帮助您理解问题。

【讨论】:

  • 我的编辑器不像 HttpListener 那样将其视为一个模块。我可以在哪里安装它?
  • 只需创建一个像HttpListener.java 这样的Java 类并将代码放在那里。这只是您需要创建的一个简单的 java 文件 - 就像您创建了活动类一样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-19
  • 1970-01-01
  • 1970-01-01
  • 2020-06-12
  • 1970-01-01
相关资源
最近更新 更多