I'm using the Android Asynchronous Http Client. My code looks like this and is working fine.
DataUtil.post("RegisterUser", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String answer) {
// initialize variables
JSONObject json = new JSONObject();
String message = null;
try {
// turn string into JSONObject
json = new JSONObject(answer);
message = json.getString("message");
} catch (JSONException e) {
Log.e("ERROR", e.getMessage());
}
// registration was successful
if (message.equals("success")) {
// forward to login page
} else {
// error
}
}
});
I implemented a static HTTP Client. My server returns this JSON data {"message":"success"}. I do not want to treat it as a String and cast it back to JSON. But when I change it to public void onSuccess(JSONObject answer) eclipse tells me
The method onSuccess(JSONObject) of type new
AsyncHttpResponseHandler(){} must override or implement a supertype
method
The correct method signature would be this public void onSuccess(int statusCode, Header[] headers, JSONObject response) or any of the other available methods in the JsonHttpResponseHandler class
Related
Hy!
I want to make some http calls to a restserver from my android client. I created a class for rest calls.
I followed the http://loopj.com/android-async-http/ description:
My question is that how can I send back anything from onSucces() method? For example I have the following function:
public class RestController {
public String getName() throws JSONException {
TwitterRestClient.get(url, null, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
String name;
try {
name = response.getString("name");
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
}
How can I return the name to getName function?
function () {
...
String name = restController.getName();
...
do something with the name
Thank you very much!
I will apreciate any kind of help!
Trying to upload a file with params using loopj.
im trying to get file from Request.Files and params from Request.Form["create"]
but it is not uploading to the server.
Android Post method
try {
String createTeamURL = "http://url";
RequestParams params = new RequestParams();
params.put("file", new File(pathoffile));
params.add("create", regString);
AsyncHttpClient client = new AsyncHttpClient();
client.post(createTeamURL, params, new AsyncHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
}
#Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
} catch (Exception e) {
Log.e("createTeamPreStep", e.getMessage());
}
My Web Api c# method
[HttpPost]
public async Task<string> CreateUHS()
{
var resultString = "";
foreach(HttpPostedFileBase s in Request.Files)
{
var a=s;
}
String sdf = Request.Form["create"];
}
You need to use put for string args.
please find the below both server and client methods.
and one more thing im really worried about your naming variable. its bad. please change it. Happy coding.
String createTeamURL = "http://url";
RequestParams params = new RequestParams();
params.put("file", new File(pathoffile));
params.put("create", regString);
Server (Web api)
[HttpPost]
public async Task<string> CreateUHS()
{
var file=Request.Files[0];
String otherArg = Request.Form["create"];
}
I am trying to parse data from URL. The URL that i test in mobile browser its working fine. I am trying to parse data by AsyncHttpClient .after exection its going to onFailure method.
in dependencies add
compile 'com.loopj.android:android-async-http:1.4.9'
and I import
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import cz.msebera.android.httpclient.Header;
..
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
try {
pg1.dismiss();
String jsonStr = new String(responseBody, "UTF-8");
Log.e("Tag ","jsonStr "+jsonStr);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
pg1.dismiss();
Log.e("Tag ","fetch feeds fail");
}
});
The URL is in GET method
can any one please help me to resolve this issue
Just print responseBody in onFailure() method. if it is timeoutexception; then you can set client.setTimeout(30000); before client.get().
OR
check your url; if it its giving response in browser or not and also check keys and values. that may be server is not giving you any response.
I am doing same thing using inner class extends AsncyTask.
private class JSONWeatherTask extends AsyncTask<String, Void, Weather> {
#Override
protected Weather doInBackground(String... params) {
Weather weather = new Weather();
data = ((new WeatherHttpClient()).getWeatherData(params[0], params[1]));
Log.d("DATA", data);
try {
weathers = JSONWeatherParser.getWeather(data);
// Let's retrieve the icon
weather.iconData = ((new WeatherHttpClient()).getImage(weather.currentCondition.getIcon()));
} catch (JSONException e) {
e.printStackTrace();
}
return weather;
}
inside WeatherHttpClient class I get data using URL with HttpUrlConnection.
I currently am using AsynchttpClient to make a POST request to a web server. When I debug, I can clearly see the JSON that is being returned. However, when I set the variable to a static method in the ECUser class, I always get that the ECUser.getCurrentUser() is null which shouldn't be correct. Since all the methods in ECUser is static, I don't see what my problem is.
The same thing happens if I try to assign a jsonobject to the responseBody from the asynchttpclient call. After the anonymous class terminates, the jsonobject is always null for some reason.
private void attemptLogin(){
RequestParams params = new RequestParams();
params.put("email", userEmail.getText().toString());
params.put("password", userPass.getText().toString());
ECApiManager.post(Constants.loginAPI, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
//called when response code 200
try{
ECUser.setCurrentUser(new ECUser(responseBody));
Log.d("login", responseBody.toString());
}catch(JSONException e){
e.printStackTrace();
}
}
});
if (ECUser.getCurrentUser() == null) {
((OnLoginListener) getActivity()).loginSuccessful(false);
}
This is my ECUser Class.
public class ECUser {
private static ECUser currentUser;
private static String userToken;
private String firstName;
private String lastName;
private static String userID;
private JSONObject jObject;
private boolean loginSuccess;
public ECUser(JSONObject data) throws JSONException {
this.jObject = data;
try {
this.loginSuccess = Boolean.parseBoolean(this.jObject.getString("success"));
if (this.loginSuccess) {
this.userToken = this.jObject.getString("token");
this.firstName = this.jObject.getJSONObject("user").getString("firstname");
this.lastName = this.jObject.getJSONObject("user").getString("lastname");
this.userID = this.jObject.getJSONObject("user").getString("id");
}
} catch (JSONException e) {
e.printStackTrace();
}
}
/**
* Method that refreshes the state of the current user by calling the API again.
*/
public static void refreshCurrentUser() {
RequestParams params = new RequestParams();
params.put("token", userToken);
//Gotta put in user ID too.
params.put("user_id", userID);
// TODO: This should only call https://edu.chat/api/user, #JACOB
ECApiManager.get(Constants.refreshUserAPI, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
try {
ECUser.setCurrentUser(new ECUser(responseBody));
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
// Static
public static ECUser getCurrentUser() {
return ECUser.currentUser;
}
public static void setCurrentUser(ECUser user) {ECUser.currentUser = user;}
public static String getUserToken() {
return ECUser.userToken;
}
// Dynamic
public String getLastName() {
return this.lastName;
}
public String getFirstName() {
return this.firstName;
}
public boolean getLoginSuccessful() {
return this.loginSuccess;
}
}
You treat the login attempt in ECApiManager#post as a synchronous method, e.g. one that returns once the attempt is completed. And so, right after calling post you check the current user.
But, clearly from the name of the http client (AsynchttpClient) you can understand that the post is an asynchronous call, which means that the HTTP request will be performed in the background, and once completed successfully, it will call your JsonHttpResponseHandler#onSuccess method. This means that although the ECApiManager#post will return immediately, the current user is not set yet.
When programming in asynchronous mode, you need to handle events as they occur, and not just call everything in sequence. If you do want to make this synchronous, you will need either to use a synchronous http client (such as HttpClient or HttpUrlConnection), or add a Semaphore to wait for your HTTP request to be completed.
For example:
private void attemptLogin(){
Semaphore sema = Semaphore(1);
sema.acquire();
// ....
ECApiManager.post(Constants.loginAPI, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject responseBody) {
//called when response code 200
try{
ECUser.setCurrentUser(new ECUser(responseBody));
Log.d("login", responseBody.toString());
}catch(JSONException e){
e.printStackTrace();
}
finally {
sema.release();
}
}
});
sema.acquire();
if (ECUser.getCurrentUser() == null) {
((OnLoginListener) getActivity()).loginSuccessful(false);
}
Note, that if you use a semaphore you will need to release it upon failure as well.
I have an AsyncHttpClient that makes a get request to an url.
I will take the response of the method onSuccess().
I paste my code to a better explain..
CategoryActivity.java call method getXML of class "XMLParser". In this method it is the AsyncHttpClient.
XMLParser parser = new XMLParser(URL);
xml = parser.getXML(URL);
XMLParser.java has .getXML(url) and return a String. I create a variable xmlResponse to put response value but it doesn't.
public String getXML(String url) {
// get connection..
String xmlResponse = "";
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
super.onSuccess(response);
xmlResponse = response;
}
#Override
public void onFailure(Throwable e) {
ma.showUserAlertQuestion();
}
});
return xmlResponse;
}
How can I get back this value?
Thank you in advance & sorry for my bad english.
This is actually a race condition. The reason why you cannot get the value of xmlResponse is because your HTTP request is an asynchronous method, the result returned before it gets back the response from the server.
This answer basically explains everything, to get the response value of onSuccess(), you need to use an interface:
public Interface XMLCallback {
onSuccess(String response);
}
In your parser class:
public String getXML(String url, XMLCallback callback) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String response) {
super.onSuccess(response);
callback.onSuccess(response);
}
#Override
public void onFailure(Throwable e) {
ma.showUserAlertQuestion();
}
});
}
And in your activity class:
private String XMLResponse = "";
XMLParser parser = new XMLParser(URL);
xml = parser.getXML(URL, new XMLCallback() {
#Override
public void onSuccess(String response) {
XMLResponse = response;
}
});
I've got the same problem of you in other context. You can see it here: https://stackoverflow.com/questions/21578458/return-asynch-data-to-method-android-java
I am also searching for a solution, but didn't find it at this moment.
The reason why you get no results in your return value, is simple. When you do: client.get() the message is send to the server. Than your code goes inmediatly to return xmlResponse. The onSucces method will be called after the return, this is because the software reaches faster the return statement than the message from the Async call is returned by the server.
In the topic I showed you above is a solution for it. But that solution didn't fit for the way I planned my application. Maybe it will fit at your application.