无法弄清楚要在OkHttp的onResponse方法中检查什么

问题描述 投票:3回答:4

我知道OkHttp有很多教程,但基本上所有这些教程都在onResponse方法中做了一些不同的事情,大多数人都懒得解释原因。一些检查if (response.isSuccessful),一些用try/catch围绕它,有些根本不做这些。

这是我的示例项目。处理onResponse方法的正确方法是什么?

public class MainActivity extends AppCompatActivity {

private TextView textViewResult;

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

    textViewResult = findViewById(R.id.text_view_result);

    OkHttpClient client = new OkHttpClient();

    String url = "https://reqres.in/api/users?page=2";

    Request request = new Request.Builder()
            .url(url)
            .build();

    client.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
            e.printStackTrace();
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            final String myResponse = response.body().string();

            MainActivity.this.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    textViewResult.setText(myResponse);
                }
            });
        }
    });
}

}

android networking okhttp
4个回答
3
投票

更新

onResponse of okhttp runs on background thread。所以,是的,有必要做MainActivity.this.runOnUiThread(...)

原始答案

onResponse回调已经在ui线程AFAIK上运行。所以,你实际上不需要做MainActivity.this.runOnUiThread(...)

每个人的onResponse都不同,因为每个人都有不同的需求。如果您在try/catch中的操作可能会出错并且您不希望它崩溃,请使用onResponse

对于某些网络请求,您可能需要检查response是否成功,否则您可能不会。这一切都取决于用例。做最适合你的方法。

我建议你在onResponse块中的try/catch中包含你的代码,因为用户可能会在网络请求完成之前关闭应用程序。当你在onResponse中设置textview文本时,它会崩溃,因为活动和textview不再存在。


2
投票

从rafid添加答案。基本上有三种情况需要检查。

  1. response.isSuccessful() =>状态代码在200到300之间
  2. response.code() =>在响应不成功后手动检查
  3. onFailure() =>网络错误或解析错误等。

理想情况下,你的回调会处理类似的情况

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        // network error or parsing error
    }
    @Override
    public void onResponse(Call call, Response response) {
        if (response.isSuccessful()) {
            // do stuff all good
        } else {
            // handle different cases for different status codes or dump them all here
        }
    }
});

你需要try-catch的原因是因为OkHttp试图解析响应。例如response.errorBody().string();就是这种情况。另一种情况是,如果你的Callback<T>实际上有一个类型参数。 OkHttp将再次尝试解析对该类型的响应。如果失败,将导致回调到onFailure方法。


0
投票

我想你需要确保你知道请求的法律回应,比如jsonFile。如果它只是一个json,请使用如下:

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                final String myResponse = response.body().string();
                if (response.isSuccessful() && !TextUtils.isEmpty(myResponse)) {
                    MainActivity.this.runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textViewResult.setText(myResponse);
                        }
                    });
                }
            }

0
投票

编辑:更清楚。

回调正在mainThread中运行,因此无需调用runOnUiThread。如果响应不成功,您可以尝试解析错误正文,如下所示。如果响应成功,你可以像我展示的那样用Gson解析。

String message = "";
            if (response.errorBody() != null) {
                try {
                    message = response.errorBody().string();
                } catch (IOException ignored) {
                    Log.e("OkHttp IOException", "error while parsing response");
                }
                 Log.d("Error Message", message);   
            }

我建议你使用Gson Library。首先,你应该创建你的pojo类。您可以使用http://www.jsonschema2pojo.org/创建您的pojo类。然后你可以解析下面的身体

  Gson gson = new Gson();
  MyPojo myPojo = gson.fromJson(response.body().charStream(), MyPojo.class);
© www.soinside.com 2019 - 2024. All rights reserved.