Reputation: 41
I know there are lots of tutorials for OkHttp, but basically all of them do something different in the onResponse
method and most don't bother to explain why. Some check for if (response.isSuccessful)
, some surround it with try/catch
, some don't do any of this at all.
This is my example project. What is the proper way to handle the onResponse method?
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);
}
});
}
});
}
}
Upvotes: 4
Views: 2567
Reputation: 1299
Edit: To be more clear.
Callback is running in mainThread so there is no need to call runOnUiThread. If response is not successful you can try to parse error body as below. If response is successful you can parse with Gson as i show.
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);
}
I recommend you to use Gson Library. First you should create your pojo class. You can use http://www.jsonschema2pojo.org/ to create your pojo class. Then you can parse body like below
Gson gson = new Gson();
MyPojo myPojo = gson.fromJson(response.body().charStream(), MyPojo.class);
Upvotes: 0
Reputation: 3021
Update
onResponse
of okhttp runs on background thread. So, yes, it's necessary to do MainActivity.this.runOnUiThread(...)
.
Original answer
onResponse
callback already runs on ui thread AFAIK. So, you don't actually need to do MainActivity.this.runOnUiThread(...)
.
And everyone's onResponse
is different because everyone has different needs. Use try/catch
if your operations in onResponse
might give error and you don't want it to crash.
For some network requests you may need to check if response
is successful for other you may not. It all depends on use cases. Do what works for you best.
I'd suggest you surround your code in onResponse
in a try/catch
block because the user might close the app before the network request is finished. And when you set the textview text in onResponse
it will crash because the activity and that textview
doesn't exist anymore.
Upvotes: 3
Reputation: 31
I think you need to make sure you know the legal response from the request, like an json
or File
. if it's just a json
, use like below:
@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);
}
});
}
}
Upvotes: 0
Reputation: 37604
Adding to the answer from rafid. There are basically three cases you want to check.
response.isSuccessful()
=> status code between 200 and 300response.code()
=> to manually check after response is not successfulonFailure()
=> Network error or parsing error etc.Ideally your callback would handle those cases something like
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
}
}
});
The reason you need a try-catch
is because OkHttp is trying to parse the response. This is the case for example for response.errorBody().string();
. Another case would be if your Callback<T>
has actually a type parameter. Again OkHttp will try to parse the response to that type. If it fails it will result in a callback onto the onFailure
method.
Upvotes: 2