Multiple OkHttp newCall not executing at once - android

So I will be making multiple GET requests and would love for them to execute all at once. However, as it is right now I have to hit the sign in button twice for the second newCall to go off. I would prefer if more newCall went off. But looking at it, the second newCall needs the response from the first one before it can. Is there a way that once the first gets the response, the second one executes instead of having to hit the sign in button twice?
Button code:
SignInButton signInButton = (SignInButton) findViewById(R.id.sign_in_button);
signInButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (authPreferences.getUser() != null && authPreferences.getToken() != null) {
System.out.println(authPreferences.getToken());
doCoolAuthenticatedStuff();
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
//new RetrieveFeedTask().execute();
} else {
chooseAccount();
}
}
});
run() code
public void run() throws Exception {
Request request = new Request.Builder()
.url(API_URL + authPreferences.getToken())
.build();
client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
try
{
String token = response.body().string();
JSONObject json = new JSONObject(token);
commatoken = json.getString("access_token");
} catch (JSONException e)
{
}
// commatoken = response.body().string();
// System.out.println(commatoken);
}
});
final Request dataRequest = new Request.Builder()
.header("content-type", "application/x-www-form-urlencoded")
.header("authorization", "JWT "+ commatoken)
.url(ChffrMe_URL).build();
client.newCall(dataRequest).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response responseMe) throws IOException {
if (!responseMe.isSuccessful()) throw new IOException("Unexpected code " + responseMe);
Headers responseHeaders = responseMe.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
try
{
String myInfo = responseMe.body().string();
JSONObject json = new JSONObject(myInfo);
commaMyInfo = json.getString("points");
} catch (JSONException e)
{
}
runOnUiThread(new Runnable() {
#Override
public void run() {
responseView.setText("Comma Points: " +commaMyInfo);
}
});
//responseView.setText(responseMe.body().string());
//System.out.println(responseMe.body().string());
}
});
}

Related

Get results of multiple network requests when they are all done

I'm running multiple network requests(getResponse method) in a for loop and I'm trying to get list of the responses only when ALL of the network requests are done.
I am trying to use CompletableFuture. getResponse uses OKHttp (asynch request and response)
Log.d("api_log", "Started doing things");
List<CompletableFuture> futures = new ArrayList();
for (int i = 0; i < mylist.size(); i++) {
try {
int finalI = i;
futures.add(CompletableFuture.runAsync(() -> getResponse(context, mylist.get(finalI).id)));
}
catch (Exception e) {}
}
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenRunAsync(() -> Log.d("api_log", "Ended doing things"));
This is the getResponse method:
private void getResponse(final Context context, final String id) {
Log.d("api_log", "id is: " + id);
final String url = context.getString(R.string.myurl) + "/" + id;
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url(url)
.method("GET", null)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
return;
}
// response HAS RECEIVED
final String strResponse = response.body().string();
Log.d("api_log", "response: " + strResponse);
}
});
}
Actual: "Ended doing things" is printed before all the responses are printed.
Expected: "Ended doing things" should be printed after all the responses are printed.
How can I achieve it?

503 HTTP response code with Twitter OAUTH

I try to get authorization token from Twitter (app-only), the code almost fully follows oficial guide, but get 503 Service unavailable code.
#Override
protected Boolean doInBackground(Void... params) {
String cred_enc = tw_cons_key + ":" + tw_priv_cons_key;
cred_enc = Base64.encodeToString(cred_enc.getBytes(), Base64.NO_WRAP);
Request request = new Request.Builder().url("https://api.twitter.com/oauth2/token")
.header("Authorization:", "Basic " + cred_enc)
.header("Content-Type:", "application/x-www-form-urlencoded;charset=UTF-8")
.post(RequestBody.create(MEDIA_TYPE_MARKDOWN, postBody))
.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 {
ResponseBody body = response.body();
if (response.isSuccessful()) {
Headers headers = response.headers();
//response check
for (int i = 0; i < headers.size(); i++) {
System.out.println("Headers: " + i + " " + headers.name(i) + " : " + headers.value(i));
}
System.out.println(body.string());
try {
JSONObject jsonObject = new JSONObject(body.string());
} catch (JSONException e) {
e.printStackTrace();
}
} else {
throw new IOException("Unexpected code" + response);
}
body.close();
}
});
return true;
}
What may be the possible reason?
It required me to write a simple server on localhost to find out what HTTP request was actually generated.
The problem was with colons: .header("Authorization:"resulted in Authorization:: in the network request!
After I removed colons from the header key values, both HttpUrlConnection and OkHttp code variants worked seamlessly.

Android: OkHttp request within AsyncTask is called twice

I have a OkHttp request within an async taks doInBackgroun(), The resquest is a bit heavy and takes some time on my backend. Unfortunatly it looks like when OKHttp doesn't get an answer straight away it tries again, this makes my server blow up !
I have tried to disable this function but it seems to ignore it... What could i do ?
public class AsyncUpdateNewPatients extends AsyncTask<Object, Void, Boolean> {
private static OkHttpClient okHttpClient;
private static DatabaseHandler db;
ActivityMain activityMain;
public AsyncUpdateNewPatients (ActivityMain atv)
{
this.activityMain = atv;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
#Override
public void log(String message) {
Stormpath.logger().d(message);
}
});
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient = new OkHttpClient.Builder()
.addNetworkInterceptor(httpLoggingInterceptor)
.retryOnConnectionFailure(false)
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15L, TimeUnit.SECONDS)
.writeTimeout(15L, TimeUnit.SECONDS)
.build();
db = new DatabaseHandler(activityMain);
}
#Override
protected Boolean doInBackground(Object... objects) {
List<PatientData> allNewPatients = db.getAllNewPatients();
JSONArray allNewPatientJSONArray = new JSONArray();
for (PatientData tempPatientObject : allNewPatients) {
JSONObject tempPatientJSON = new JSONObject();
try {
tempPatientJSON.put("firstName", tempPatientObject.getFirstName());
tempPatientJSON.put("lastName", tempPatientObject.getLastName());
tempPatientJSON.put("height", tempPatientObject.getHeight());
tempPatientJSON.put("weight", tempPatientObject.getWeight());
tempPatientJSON.put("vaccines", tempPatientObject.getVaccinHistory());
tempPatientJSON.put("address", tempPatientObject.getAddress());
tempPatientJSON.put("zone", tempPatientObject.getZone());
tempPatientJSON.put("id", tempPatientObject.getId());
String dateOfBirth = tempPatientObject.getDateOfBirth().get(Calendar.DAY_OF_MONTH) + "/" + tempPatientObject.getDateOfBirth().get(Calendar.MONTH) + "/" + tempPatientObject.getDateOfBirth().get(Calendar.YEAR);
tempPatientJSON.put("dob",dateOfBirth);
} catch (JSONException e) {
e.printStackTrace();
}
allNewPatientJSONArray.put(tempPatientJSON);
}
if(allNewPatients.size() > 0){
JSONObject bodyJSON = new JSONObject();
try {
bodyJSON.put("allNewPatients", allNewPatientJSONArray);
} catch (JSONException e) {
e.printStackTrace();
}
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
final RequestBody body = RequestBody.create(JSON, String.valueOf(bodyJSON));
Request request = new Request.Builder()
.url(activityMain.getString(R.string.main_url) + "/api/syncFromOffLine")
.headers(buildStandardHeaders(Stormpath.accessToken()))
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("DEBEUG", "error: " + e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.code() == 200){
Log.d("DEBEUG", "response: " + response.body().string());
} else {
Log.d("DEBEUG", "there was an error: " + response.message().toString());
}
}
});
}
return true;
}

Accessing OKHttp Response Body

So I need to figure out how to access the value I get from my first response in my second. I would think that I could just store it to a a variable and access it in another request. However, that does not seem to be the case.
Here is the bit that is giving me issues. So my first request is getting me a token and then I need to use that which is stored in commatoken in my second request.
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url(API_URL + authPreferences.getToken())
.build();
client.newCall(request).enqueue(new Callback() {
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
String commatoken = response.body().string();
}
});
Request dataRequest = new Request.Builder()
.header("Authorization", "jwt"+commatoken)
.url(ChffrMe_URL).build();
client.newCall(dataRequest).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0, size = responseHeaders.size(); i < size; i++) {
System.out.println(responseHeaders.name(i) + ": " + responseHeaders.value(i));
}
System.out.println(response.body().string());
}
});
}
I think we can call response.body().string() only once .... so save that data to a string variable first .. and access it wherever you need it.
String response_data;
..............
response_data = response.body().string();
You are calling response.body().string() twice ...
More info
https://stackoverflow.com/a/27922818/3552066
If you want to avoid about empty result:
assert response.body() != null;
String r = response.body().string();
And if you want access to each elements :
JSONObject json = new JSONObject(r);
Log.i("love", "Res: "+json.getString("result")); //Name -> Answer
See the result:
{"fname":"John","sname":"Alice","percentage":"46","result":"Can choose someone better."} // String from
I/love: Res: All the best! // Json form by Name

Android simple OKHTTP not working at all

Help, I don't know what's going on, but my OKHTTP aplication don't do what I want.
It starts and all, no error and so on, but don't do run() Method at all. Here's the code.
private final OkHttpClient client = new OkHttpClient();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aktualnosci);
try {
run();
} catch (Exception e) {
e.printStackTrace();
}
}
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
Headers responseHeaders = response.headers();
for (int i = 0; i < responseHeaders.size(); i++) {
Log.d("responseHeaders.name(i)", "responseHeaders.value(i)");
}
System.out.println(response.body().string());
}
How can I fix it.

Categories

Resources