Check if async request is finished, using loopj android async - android

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

Related

Can't figure out what to check for in OkHttp's onResponse method

I know there are lots of tutorials for OkHttp, but basically all of them do something different in the onResponse method and most don't bother to explain why. Some check for if (response.isSuccessful), some surround it with try/catch, some don't do any of this at all.
This is my example project. What is the proper way to handle the onResponse method?
public class MainActivity extends AppCompatActivity {
private TextView textViewResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textViewResult = findViewById(R.id.text_view_result);
OkHttpClient client = new OkHttpClient();
String url = "https://reqres.in/api/users?page=2";
Request request = new Request.Builder()
.url(url)
.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 {
final String myResponse = response.body().string();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
textViewResult.setText(myResponse);
}
});
}
});
}
}
Update
onResponse of okhttp runs on background thread. So, yes, it's necessary to do MainActivity.this.runOnUiThread(...).
Original answer
onResponse callback already runs on ui thread AFAIK. So, you don't actually need to do MainActivity.this.runOnUiThread(...).
And everyone's onResponse is different because everyone has different needs. Use try/catch if your operations in onResponse might give error and you don't want it to crash.
For some network requests you may need to check if response is successful for other you may not. It all depends on use cases. Do what works for you best.
I'd suggest you surround your code in onResponse in a try/catch block because the user might close the app before the network request is finished. And when you set the textview text in onResponse it will crash because the activity and that textview doesn't exist anymore.
Adding to the answer from rafid. There are basically three cases you want to check.
response.isSuccessful() => status code between 200 and 300
response.code() => to manually check after response is not successful
onFailure() => Network error or parsing error etc.
Ideally your callback would handle those cases something like
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// network error or parsing error
}
#Override
public void onResponse(Call call, Response response) {
if (response.isSuccessful()) {
// do stuff all good
} else {
// handle different cases for different status codes or dump them all here
}
}
});
The reason you need a try-catch is because OkHttp is trying to parse the response. This is the case for example for response.errorBody().string();. Another case would be if your Callback<T> has actually a type parameter. Again OkHttp will try to parse the response to that type. If it fails it will result in a callback onto the onFailure method.
I think you need to make sure you know the legal response from the request, like an json or File. if it's just a json, use like below:
#Override
public void onResponse(Call call, Response response) throws IOException {
final String myResponse = response.body().string();
if (response.isSuccessful() && !TextUtils.isEmpty(myResponse)) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
textViewResult.setText(myResponse);
}
});
}
}
Edit: To be more clear.
Callback is running in mainThread so there is no need to call runOnUiThread.
If response is not successful you can try to parse error body as below. If response is successful you can parse with Gson as i show.
String message = "";
if (response.errorBody() != null) {
try {
message = response.errorBody().string();
} catch (IOException ignored) {
Log.e("OkHttp IOException", "error while parsing response");
}
Log.d("Error Message", message);
}
I recommend you to use Gson Library. First you should create your pojo class. You can use http://www.jsonschema2pojo.org/ to create your pojo class. Then you can parse body like below
Gson gson = new Gson();
MyPojo myPojo = gson.fromJson(response.body().charStream(), MyPojo.class);

internal server error 500 retrofit in android?

I am implementation for Retrofit on api call using images-upload base64Encode string. it is sending data perfect but Retrofit return response Internal Server Error 500 and i am sending request type is Body custom class. Plz help me what i do.
#Headers("Accept:application/json")
#POST(RestClient.postRegister)
Call<RegisterResp> getRegisterResponse(#Body RequestRegisterVo requestRegisterVo);
Call<RegisterResp> call = MyApplication.getRestClient().getApplicationServices().getRegisterResponse(requestRegisterVo);
call.enqueue(new Callback<RegisterResp>() {
#Override
public void onResponse(Call<RegisterResp> call, Response<RegisterResp> response) {
if (Other.isValidResp(response)) {
// success Log.i(TAG,"Register successfully");
} else {
hideDialog();
}
}
#Override
public void onFailure(Call<RegisterResp> call, Throwable t) {
hideDialog();
showToast(t.getMessage());
}
});
The same issue I had to face it, I got a solution in my case-
there is parameter issue, I was sending parameters in String and at the backend, they required Integer parameters.
You also checkout may be there is the issue with parameters or second reason is the URL issue so check it URL also.

How to implement POST method in AsyncTask to write JSON data through API in android studio?

I want to POST JSON data having nested objects in it with the help of Asynctask in android studio, but I don't have good knowledge of API implementation in android studio. I am all new in android studio. I have successfully POST this data from POSTMAN, but I am not able to implement the code for it, also I don't have any tutorials for Asynctask. Please help me to implement code for this.
This is my Json data having nested Objects in it:
You don't need Async, Volley does it in the background for you. Put your JSONObject in the method instead of 'new JSONObject'. And YourURL - i.e '/api/route/'.
RequestQueue queue = Volley.newRequestQueue(this);
JsonObjectRequest request_json = new JsonObjectRequest(YourURL, new JSONObject(params)),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do what you want on response
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//If there's an error...
}
});
//Add process to queue to get JSON in background thread
queue.add(request_json);
Nowadays a better/simpler approach would be to use a libary like Retrofit to do all the magic for you.
You can simply send a Java instance model to an API endpoint. Retrofit takes care of converting it to json when using the GsonConverterFactory class and sends the json to the endpoint you provided with the given HTTP method.
Best and Simple Library for Implementation for API services by third party library made by Square, Retrofit a Easy HTTP Client.
Why Retrofit? because, Retrofit automatically creates the background thread ,Parse the Json using GSON converter and get a call success and Failure call back directly on main thread. Without writing too much boiler plate code of AsyncTask and Parsing JSON and getting the result on main thread.
Make Retrofit Client.
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
RetrofitInterface service = retrofit.create(RetrofitInterface.class);
Make Method in RetrofitInterface.
#POST("users/new")
Call<User> yourMethod(#Body UserType user);
Now Call your method and It will make your success and Failure Callback method
Call<List<Repo>> repos = service.yourMethod("octocat");
And then Call enque method to automatic create background thread.
repos.enqueue(new Callback<List<Repo>>() {
#Override
public void onResponse(Call<List<Repo>> call, Response<List<Repo>> response) {
}
#Override
public void onFailure(Call<MainResponse> call, Throwable t) {
}
});

What is the best way to coordinate Volley requests

I'm trying to use Volley to execute multiple HTTP request where each one of them relies on the result of the previous one, what is the best option as a design?
1-Firing the next request in the onResponse callback of the previous request?
2-Writing some coordinator class that have callbacks that get called in the onResponse method of a request and fires the next request
skeleton code for the second option
coodrinator = new Coordinator();
JsonObjectRequest firstRequest = new JSONObjectRequest(Request.Method.GET,firstURL),new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//handle the responsee
coordinator.onFirstRequestRecieved();
}
},
errorListener);
private void doSecondRequest(){
JsonObjectRequest secondRequest = new JSONObjectRequest(Request.Method.GET,secondURL),new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//handle the responsee
coordinator.onSecondRequestRecieved();
}
},
errorListener);
}
private class Coordinator{
public void onFirstReequestRecieved(){
doSecondRequest();
}
public void onSecondRequestRecieved(){
//do Something
}
}
If first request response parameters are needed for making second request and so on then you can go for synchronous way. That can be achieved by making second request in onResponse on First request can there is no good or bad practise for it.
The thing is volley is asynchronous and request what is added in the queue execute without depending on other request and we are going to make it synchronous request and it can be achieved by many ways seeing your requirement.

Getting an SSL exception in retrofit

I have some problems using retrofit as my web communication interface against a php webservice contained in a worpress website - upon a call for one of the JSON API methods in the WP site I get an SSL exception on my android client even though I run over http and not https.
Here is my code -
public class RestApi {
private static final String API_URL = "https://tmc.co.nf/api";
private SmokeTalkRest service;
interface SmokeTalkRest {
#FormUrlEncoded
#POST("/get_nonce")
void getNonce(#Field("controller") String controller, #Field("method") String method, Callback<String> callback);
}
public RestApi() {
// Create a very simple REST adapter which points the GitHub API
// endpoint.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer(API_URL).build();
// Create an instance of our GitHub API interface.
service = restAdapter.create(SmokeTalkRest.class);
}
public void getNonceForMethod(Method method, Callback<String> callback) {
service.getNonce("user", method.name(), callback);
}
}
The get nonce is called upon a button click, did someone already bumped into that?
I believe the issue you are having is your trying to call retrofit but not using the async version. The callback is probably the easiest to use.
#GET("/user/{id}")
void listUser(#Path("id") int id, Callback<User> cb);
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("baseURL")
.build();
ClientInterface service = restAdapter.create(ClientInterface.class);
Callback callback = new Callback() {
#Override
public void success(Object o, Response response) {
//do something
}
#Override
public void failure(RetrofitError retrofitError) {
}
};
service.listUser(1, callback);
How to implement an async Callback using Square's Retrofit networking library
Android now requires you to do any webrequests async otherwise it will error out.
Also, retorfit will convert/parse the object for you so you dont have to. It saves time when it comes to creating async tasks and setting up the parsing. It also give a nice standard to go by when doing requests as well.

Categories

Resources