I'm using The Loopj Android Asynchronous HTTP Client to send multiple HTTP requests asynchronously.
I'm using a static AsyncHttpClient as suggested and sending multiple HTTP posts and receiving responses on an anonymous class. The problem is that when a request comes back I don't know how to tie it back to the original request.
For instance, in a caching situation, when I send a post and receive a 200 OK I need to be able to know which request that response is for so I can mark it as successfully sent.
Try this:
public class MyAsyncHttpResponseHandler extends AsyncHttpResponseHandler {
private String requestId;
public AsyncHttpResponseHandler(String requestId) {
this.requestId = requestId;
}
#Override
public void onSuccess(String arg0)
{
super.onSuccess(arg0);
// Use requestId here
}
}
Sending request:
client.get(url, new MyAsyncHttpResponseHandler(requestId))
Related
I am using HttpUrlConnection for doing requests to my mysql db using webservices. With HttpUrlConnection I can execute all my requests in background so the main thread don't get overloaded and start skipping frames.
With okHttp how does this is achieved? How do I make a request with it and print a response using JSON? Is it better than httpUrlConnection?
P.S I do not know anything about okHttp, I will be grateful if you are explicit with your examples.
With okHttp how does this is achieved?
Typically, you let it handle the background thread for you, using enqueue() for asynchronous operation:
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("http://publicobject.com/helloworld.txt")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onFailure(Call call, IOException e) {
// handle the error
}
#Override public void onResponse(Call call, Response response) throws IOException {
// use the result
}
});
}
(sightly simplified from the OkHttp docs)
Or, if you already have a background thread, you can use execute() instead of enqueue() for synchronous operation.
You might wish to review the other examples on the OkHttp recipes page, plus the OkHttp Web page, plus the OkHttp wiki, to get a better sense of how it compares with what you are used to.
The GCM Sample Project gives a stubbed out example of sending a GCM token to your server:
public class RegistrationIntentService extends IntentService {
...
#Override
protected void onHandleIntent(Intent intent) {
try {
...
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.i(TAG, "GCM Registration Token: " + token);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(token);
...
} catch (Exception e) {
...
}
}
/**
* Persist registration to third-party servers.
*
* Modify this method to associate the user's GCM registration token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
but this is done in an IntentService which finishes as soon as onHandleIntent returns right? So if starting an http call to send the token with the popular android-async-http library, I'm not even seeing my onStart hit:
private void sendRegistrationToServer(String token) {
post("/devices", params, new AsyncHttpResponseHandler() {
// TODO: MAKE SURE ONSTART ACTUALLY CALLED TO MAKE SURE REQUEST AT LEAST GOES UPSTREAM EVEN IF I DON'T RECEIVE A CALLBACK SINCE IN INTENTSERVICE
// IF NOT THEN MIGHT HAVE TO CHANGE THE INTENTSERVICE TO A SERVICE FOR DEVICE REGISTRATION
#Override
public void onStart() {
// not actually using callback because request sent from intentservice
Log.d("tagzzz", "sending upstream");
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
// not actually using callback because request sent from intentservice
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
// not actually using callback because request sent from intentservice
}
});
}
Will my http request even be sent upstream before onHandleIntent returns and finishes the IntentService? If not, why does Google give this as their example for sending your token to your server?
Will my http request even be sent upstream before onHandleIntent returns and finishes the IntentService?
Given that you are using a library named "android-async-http", I would assume that the default behavior is for it to execute the HTTP asynchronously. It is indeterminate whether or not the post() call will complete its work before onHandleIntent() returns, but it seems unlikely.
why does Google give this as their example for sending your token to your server?
Google doesn't. Google has a stub sendRegistrationToServer(), as you can see in your first code listing. I am not aware of any Google examples that use the "android-async-http" library.
You decided to use an asynchronous mechanism for sending that HTTP request. That is an inappropriate choice for inside an IntentService. Now, perhaps that library has a synchronous option, in which case you could switch to that. Otherwise, use something else synchronous for the HTTP request (HttpURLConnection, OkHttp3, etc.) from the IntentService.
Note that Volley is not a great choice here, insofar as Volley is also strongly tilted towards asynchronous work.
I am developing an android app that uses Android Async. I am using this library called Android Asynchronous Http Client
I made a method for a GET request
public String getVenues(String token) throws Exception {
AsyncHttpClient venuesReq = new AsyncHttpClient();
venuesReq.addHeader("Authorization", "Token token=" + token);
venuesReq.get(mainAct.httpRequestURL + "/venues", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
venues = response;
}
#Override
public void onFinish() {
// Completed the request (either success or failure)
}
return venues;
}
but when I call getVenues("token") the return is null, but when I try to call getVenues("token") after few seconds there are now results for venues.
I know that I am using async request so the venues doesn't return immediately.
Now what I want is, when I call getVenues("token") method there should be a returned response for the GET Request.
You need to use interface here take a look at this
https://stackoverflow.com/a/21773406/472336
Your class from where you are listening/asking for asyntask result need to impliment interface and call that interface method from asyntask..
Hope this helps
Is there a nice way to implement "blocking" request interceptor?
The main idea is that all requests should be intercepted and added additional header - token.
If token does not exist yet it should be retrieved first, then added to that request and cached for future used. token is retrieved via API call.
I've tried to do synchronous request, but, that produces android.os.NetworkOnMainThreadException. And implementing with in_progress flags it doesn't look nice.
You can already do the 'intercept' part of this using RequestInterceptor. Just use RestAdapter.Builder.setRequestInterceptor().
It's a better idea to retrieve the token from the API outside the RequestInterceptor though, as it's not meant to do that. After that first call, you can just add the token anywhere you want in your requests inside RequestInterceptor.intercept().
Something like this:
Builder builder = new RestAdapter.Builder()
//Set Endpoint URL, Retrofit class... etc
.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
String authToken = getAuthToken(); //Not included here, retrieve the token.
request.addHeader("Authorization", "Bearer " + authToken);
}
);
Well, you have already implemented your 'blocking' interceptor, your problem is android doesn't let you block the main thread with network calls.
You should probably wrap your retrofit calls in a service class that calls, asynchronously, to your getToken method, and makes the 'main' request only if and when that first one completes succesfully.
As of OkHTTP 2.2, you can now add interceptors that run on the network thread:
https://github.com/square/okhttp/wiki/Interceptors
An example interceptor for adding an auth token might be like this;
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
// Get your auth token by going out over the network..
// add authorization header, defaulting to the original request.
Request authedRequest = request;
if (!TextUtils.isEmpty(authToken)) {
authedRequest = request.newBuilder().addHeader("Auth", authToken).build();
}
return chain.proceed(authedRequest);
}
I am developing an Android app using Parse.com website. In which whatever user sends data that must be received by receiver, but here I have to use REST api. I succeeded to send data to Parse website but now I have to Push that data with the help of REST api only. I am confused with REST api. Help to solve it.
You can use a library for that. I would suggest this one https://github.com/kodart/Httpzoid
It has clean API and type-safe data.
Here is a simple usage example
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.execute();
Or more complex with callbacks
Http http = HttpFactory.create(context);
http.post("http://example.com/users")
.data(new User("John"))
.handler(new ResponseHandler<Void>() {
#Override
public void success(Void ignore, HttpResponse response) {
}
#Override
public void error(String message, HttpResponse response) {
}
#Override
public void failure(NetworkError error) {
}
#Override
public void complete() {
}
}).execute();
It is fresh new, but looks very promising.