无法在OkHttp的onResponse方法中找出要检查的内容

时间:2017-12-21 11:21:52

标签: android networking okhttp

我知道有很多关于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);
                }
            });
        }
    });
}

}

4 个答案:

答案 0 :(得分: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不再存在。

答案 1 :(得分:2)

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

  1. response.isSuccessful() =&gt;状态代码介于200和300之间
  2. response.code() =&gt;在响应不成功后手动检查
  3. onFailure() =&gt;网络错误或解析错误等。
  4. 理想情况下,您的回调会处理类似

    的情况
    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方法。

答案 2 :(得分: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);

答案 3 :(得分: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);
                        }
                    });
                }
            }