我知道有很多关于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);
}
});
}
});
}
}
答案 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的答案。基本上有三种情况需要检查。
response.isSuccessful()
=&gt;状态代码介于200和300之间response.code()
=&gt;在响应不成功后手动检查onFailure()
=&gt;网络错误或解析错误等。理想情况下,您的回调会处理类似
的情况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)
我认为您需要确保知道请求的法律回复,例如json
或File
。如果它只是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);
}
});
}
}