Reputation: 57
I want to get string JSON response to the main activity after making the connection I know it is running in different thread so please help me how I can get it and then return it from this method;
public class MakeNetworkConnection {
private String mBaseUrl;
private String mApiKey;
private String mContentType;
private String mJsonResponce;
public MakeNetworkConnection(String baseUrl, String apiKey, String contentType) {
mBaseUrl = baseUrl;
mApiKey = apiKey;
mContentType = contentType;
}
public String startNetworkConnection() throws IOException {
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder().url("http://content.guardianapis.com/sections?api-key=1123456").build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
mJsonResponce=response.body().string();
}
}
});
return mJsonResponce;
}
}
Upvotes: 0
Views: 4490
Reputation: 6791
The problem here is about understanding how asynchronous tasks work. When you are calling client.newCall(request).enqueue(new Callback()
, it will run in the background thread (off the main thread) and control will pass to the next line which is return mJsonResponce;
And thus, it will always return null
.
What you should do is to pass a callback method which will be called when the response is successful. You can create an interface to return the result:
public interface NetworkCallback {
void onSuccess(String response);
void onFailure();
}
Pass an object of this interface while making the network request and call appropriate method when network request finishes.
One more thing you will have to take care is that OkHttp
doesn't return the response on the main thread, so you will have to return the response on UI/main thread if you are going to update any UI. Something like this will work.
@Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()){
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
//return response from here to update any UI
networkCallback.onSuccess(response.body().string());
}
});
}
}
Upvotes: 2
Reputation: 57
after advice from Rohit Arya i did the following:
public class OkHttpUtil {
public interface OKHttpNetwork{
void onSuccess(String body);
void onFailure();
}
public void startConnection(String url, final OKHttpNetwork okHttpCallBack) throws IOException {
OkHttpClient client=new OkHttpClient();
Request request=new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (response.isSuccessful()){
okHttpCallBack.onSuccess(response.body().string());
}
}
});
}
}
in the MainActvity i did the following :
OkHttpUtil okHttpUtil=new OkHttpUtil();
try {
okHttpUtil.startConnection("http://content.guardianapis.com/sections?api-key=8161f1e9-248b-4bde-be68-637dd91e92dd"
, new OkHttpUtil.OKHttpNetwork() {
@Override
public void onSuccess(String body) {
final String jsonResponse=body;
runOnUiThread(new Runnable() {
@Override
public void run() {
//show the response body
Toast.makeText(MainActivity.this,jsonResponse, Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onFailure() {
//do something
}
});
} catch (IOException e) {
e.printStackTrace();
}
Upvotes: 0
Reputation: 39843
Instead of using calls asynchronously, you could use it synchronously with execute()
.
public String startNetworkConnection() throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://content.guardianapis.com/sections?api-key=1123456")
.build();
return client.newCall(request)
.execute()
.body()
.string();
}
Upvotes: 0
Reputation: 302
Change this line
mJsonResponce=response.body().toString();
To
mJsonResponce=response.body().string();
Hope help you.
Upvotes: -1