Android how to get response string from Callback using OkHttp?
Solution 1
I think what you want to do is something like this:
public class MyActivity extends Activity implements Callback , View.OnClickListener {
@Override
public void onCreate(Bundle savedState) {
super.onCreate(savedState);
findViewById(R.id.DoHttp).setOnClickListener(this);
}
@Override
public void onClick(View v) {
if (v.getId(() == R.id.DoHttp) {
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build();
okHttpClient.newCall(request).enqueue(this);
}
}
@Override
public void onFailure(Request request, IOException e) {
//do something to indicate error
}
@Override
public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
parse(response.body().string());
}
}
private void parse(String response) {
//do something with response
}
}
In the above activity we implement Callback and then when we create the okhttp request, we pass it an instance of ourself (this) and that way we can get oktthp to call back the class, we could have done an inner class just as easily but this reduces the # of classes we have to make. I used a button click to illustrate when the Http call is made but that could be some other time, for instance it could happen when the screen is first created (in onCreate). Be careful though of screen rotations. Also this assumes that the callback is done on the main thread which I think it would be but I'm not positive as I use okttp in a different way than you. If it does not return the results on the response on the main thread then you can call runOnUiThread() and pass it a Runnable that does the work of updating the views.
Solution 2
If you move the responseString
declaration to be an instance variable then you will be able to assign its value in the onResponse
method of your Callback
.
public class MyClass {
private String responseString;
// your class implementation
}
I have modified the code you posted with the necessary changes below:
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build();
Callback callback = new Callback() {
@Override
public void onFailure(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
responseString = response.body().string();
}
};
okHttpClient.newCall(request).enqueue(callback);
Solution 3
First answer is close, but you cannot assign final variable in method onResponse. Workaround is to type final String[] responseString = new String[1];
and assign responseString[0] = response.body().string();
tm-null
Updated on June 22, 2022Comments
-
tm-null almost 2 years
This is my code:
OkHttpClient okHttpClient = new OkHttpClient(); Request request = new Request.Builder().url("http://publicobject.com/helloworld.txt").build(); Callback callback = new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(Response response) throws IOException { } }; okHttpClient.newCall(request).enqueue(callback); String responseString;
In the above code, I want to store the value of response.body().string() from the onResponse() method in the variable responseString, however I can't access it.
-
Matt Wolfe almost 9 yearsI'm kind of confused what you are trying to do here. If this code exists in a local function then what good does it do to use an asynchronous callback and store a variable declared in the calling function? You wouldn't be able to use that anyways unless you block first. You could store the response in a class instance variable instead and that would work fine. More than likely though you're going about this the wrong way.
-
tm-null almost 9 years@MattWolfe you are probably right, I am new to Android development. What I am trying to do is get some data like this link, save it in a variable, parse it and then display it on the screen using a View. Would storing the data in an instance variable be the right way to do this or is there another way? Thank you.
-
Matt Wolfe almost 9 yearsI would just have your activity/fragment implement Callback: Then do: okHttpClient.newCall(request).enqueue(this); Then in your onResponse parse it and you can display the results to screen.
-
-
tm-null almost 9 yearsUnfortunately I can't change the value of responseString inside onResponse since it is final
-
tm-null almost 9 yearsAfter changing my code, gist.github.com/taimoor-ahmad/ef9515751294d80d460e I get java.lang.NullPointerException: println needs a message when trying to use the value of responseString[0] in my Log
-
Tomek almost 9 yearsbecouse code in onResponse was not yet called back, you have to print it after callback execution
-
Andrea Thacker almost 9 yearsYou are perfectly correct, sorry for the mistake. I have modified my code but if it is no longer useful I will remove it.
-
tm-null almost 9 yearsThank you. It turns out that code does work, however it takes a while for the value of responseString to be updated.
-
Andrea Thacker almost 9 yearsYes, that is because it happens asynchronously and depends on the response time of the network and the endpoint you are receiving data from. That will be the case for all applications that are receiving data from an internet source.
-
Pb Vignesh almost 7 yearsCan you post an example/link of something you would use, because the above method as you said would execute the network call every time on screen rotation right?
-
Matt Wolfe almost 7 yearsThis is a common problem without a single or simple solution.
-
Matt Wolfe almost 7 years