I want to start new activity after call and finish 7 difference requests in parallel using retrofit.
Where should I call startActivity() method?
here is my wrong trying.
new Thread(new Runnable() {
#Override
public void run() {
api.method1(args..).enqueue(new Callback<Response1>() {
#Override
public void onResponse(Call<Response1> call, Response<Response1> response) {
//do some things
}
#Override
public void onFailure(Call<Response1> call, Throwable t) {
t.printStackTrace();
}
});
..
..
..
api.method7(args..).enqueue(new Callback<Response7>() {
#Override
public void onResponse(Call<Response7> call, Response<Response7> response) {
//do some things
}
#Override
public void onFailure(Call<Response7> call, Throwable t) {
t.printStackTrace();
}
});
startActivity(new Intent(current.this,next.class));
}).start();
Use Rxjava with Retrofit and then you can do something like (assuming method1,method2 etc return Observable<Response1>, Observable<Response2> etc)
Observable.zip(api.method1, api.method2, ...)
Related
in retrofit Client When Create data OnResponse Not Call
but Passing In the database
I cant intern in Another Activity.
public void saveUser(StudentName studentName){
Call<StudentName>call =ApiClient.getStudentName().sendStudentName(studentName);
call.enqueue(new Callback<StudentName>() {
#Override
public void onResponse(Call<StudentName> call, Response<StudentName> response) {
Intent intent = new Intent(StudentData.this,MainActivity.class);
startActivity(intent);
}
#Override
public void onFailure(Call<StudentName> call, Throwable t) {
}
});
here is my code:
by this method, I send some data to my API server
if data received successfully success variable will be true inside onResponse method
private boolean success=false;
public boolean commit(){
requestHandler.insertFields(tableName,values).enqueue(new Callback<DatabaseModel>() {
#Override
public void onResponse(Call<DatabaseModel> call,
Response<DatabaseModel> response) {
if (response.isSuccessful())
Log.i("debug8","result is:"+response.body().toString());
else
Log.e("debug8","error in server response:"+response.toString());
success=true;
}
#Override
public void onFailure(Call<DatabaseModel> call, Throwable t) {
Log.e("tempo",t.getMessage());
}
});
return success;//returns false before finishing the request
}
and in my activity i want to check the result like this:
Database db=new Database("cars");
db.put("field1","val1")
.put("field2","val2");
if(db.commit())
Toast.makeText(this, "data inserted successfully", Toast.LENGTH_SHORT).show();
else
Toast.makeText(this, "failed to insert new record", Toast.LENGTH_SHORT).show();
the problem is that always the commit method result is false because code returns false before retrofit enqueue method finishes its job
is it a good idea to make a custom listener or something like that to do this?
thanks in advance
Yes,you need to create listener for this because these calls happen asynchronously that's why it's returning always false.
You can create a interface like below.
public interface RetrofitResponseListener {
void onSuccess();
void onFailure();
}
And pass it as a argument in your method.
public void commit(final RetrofitResponseListener retrofitResponseListener) {
requestHandler.insertFields(tableName, values).enqueue(new Callback<DatabaseModel>() {
#Override
public void onResponse(Call<DatabaseModel> call,
Response<DatabaseModel> response) {
if (response.isSuccessful())
retrofitResponseListener.onSuccess();
else
retrofitResponseListener.onFailure();
}
#Override
public void onFailure(Call<DatabaseModel> call, Throwable t) {
retrofitResponseListener.onFailure();
}
});
}
And finally use this where you like:
private void setListener() {
commit(new RetrofitResponseListener() {
#Override
public void onSuccess() {
}
#Override
public void onFailure() {
}
});
}
Now do anything you want onSuccess or onFailure.
what happens there is the next: the request method is an async task, when you call it, it´ll start working on a second plane and your commit function continues with its sync flow which is return (the false value in this case).
you can try 2 things:
something like this,
public XX(whatever correspond) commit(){
return requestHandler.insertFields(tableName,values).enqueue(new Callback<DatabaseModel>() {
#Override
public void onResponse(Call<DatabaseModel> call,
Response<DatabaseModel> response) {
if (response.isSuccessful())
Log.i("debug8","result is:"+response.body().toString());
else
Log.e("debug8","error in server response:"+response.toString());
return true;
}
#Override
public void onFailure(Call<DatabaseModel> call, Throwable t) {
Log.e("tempo",t.getMessage()); return false;
}
});
}
and fix the if at the other side
or this way
public void commit(){
requestHandler.insertFields(tableName,values).enqueue(new Callback<DatabaseModel>() {
#Override
public void onResponse(Call<DatabaseModel> call,
Response<DatabaseModel> response) {
if (response.isSuccessful())
Log.i("debug8","result is:"+response.body().toString());
else
Log.e("debug8","error in server response:"+response.toString());
Toast.makeText(this, "data inserted successfully", Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(Call<DatabaseModel> call, Throwable t) {
Toast.makeText(this, "failed to insert new record", Toast.LENGTH_SHORT).show();
}
});}
I am using a ProgressDialog to be presented before making a Rest request using Retrofit + RxJava, the response of the request is large and this is freezing the animation of ProgressDialog. How can I fix this? I only found examples saying to use runOnUiThread or the doInBackground with AsyncTask but, I'm using RxJava. I tried the runOnUiThread but it did not work.
//My request
public void getMyData(final MyListener listener) {
AppApi AppApi = getInstanceMyApi();
AppApi.getMyData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<ResponseData>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
//error
}
#Override
public void onNext(ResponseData response) {
//success, send data to presenter to update view
}
});
//Presenter call ws
public void attemptGetDataFromWS() {
showProgress();
getMyData(this);
}
#Override
public void onGetMyDataSuccess(ResponseData response) {
hideProgress();
}
#Override
public void onGetMyDataError(String error) {
hideProgress();
}
public void getMyData(final MyListener listener) {
AppApi AppApi = getInstanceMyApi();
AppApi.getMyData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new DisposableObserver<ResponseData>() {
#Override
public void onCompleted() {
dispose();
}
#Override
public void onError(Throwable e) {
listener.onGetMyDataError(e.getMessage());
}
#Override
public void onNext(ResponseData response) {
listener.onGetMyDataSuccess(response);
}
});
//Presenter call ws
public void attemptGetDataFromWS() {
showProgress();
getMyData(this);
}
#Override
public void onGetMyDataSuccess(ResponseData response) {
hideProgress();
}
#Override
public void onGetMyDataError(String error) {
hideProgress();
}
Follow this method .this is calling example with REST API + Retrofit
private void callRestAPI() {
Retrofit retrofit = new Retrofit.Builder().baseUrl(BASEURL)
.addConverterFactory(GsonConverterFactory.create())
.build();
newsAPI = retrofit.create(NewsAPI.class);
Call<JSONResponse> call = newsAPI.topNews("soure", "api-key");
// Set up progress before call
final ProgressDialog progressDoalog;
progressDoalog = new ProgressDialog(MainActivity.this);
progressDoalog.setMax(100);
progressDoalog.setMessage("Its loading....");
progressDoalog.setTitle("ProgressDialog bar example");
progressDoalog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// show it
progressDoalog.show();
call.enqueue(new Callback<JSONResponse>() {
#Override
public void onResponse(Call<JSONResponse> call, Response<JSONResponse> response) {
// close it after response
progressDoalog.dismiss();
}
}
#Override public void onFailure (Call < JSONResponse > call, Throwable t){
// close it after response
progressDoalog.dismiss();
}
});
}
I want to make a REST Client with Android and I read about retrofit. When I do some requests with retrofit even if the activity is destroyed the callback is executed.
How can I stop receiving the response after the activity is being destroyed?
apiService.getDummieContent().enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
You can assign the request to a variable and cancel it on activity destroy:
Call<ReponseBody> call = apiService.getDummieContent();
call.enqueue(...);
#Override
protected void onDestroy() {
super.onDestroy();
call.cancel();
}
You can declare global variable apiService
Call<ReponseBody> apiService;
and then call api method for instance here getDummieContent().Moreover you can manually check for the if call is cancelled in OnFaliure method. As in my case i was disabling swipeRefreshLayout which was getting null context on DestroyView because onFailure method was only called when view was destroyed, so with the help of this condition i always checked whether it is cancelled after on destroyed hence preventing exception.
apiService.getDummieContent().enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response)
{
// Do stuff here
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
t.printStackTrace();
if(call.isCanceled())
{
Log.e("isCanceled", " isCanceled");// check if it is cancelled on OnDestroy
}
}
});
and in on destory onDestroy
#Override
public void onDestroy() {
super.onDestroy();
call.cancel();
}
I have a fragment where I post request to server. This type of action should be in onResume() method, but I don't want to post request to server every time when I put app on background. Is exist any solution?
request which I want to post
FactoryAPI.getContacts().getContacts(user.getToken()).enqueue(new Callback<ContactsResponse>() {
#Override
public void onResponse(Call<ContactsResponse> call, Response<ContactsResponse> response) {
if(response.isSuccessful()) {
contactList = response.body().getContactsList();
sortList();
progressDialog.dismiss();
setRecyclerView();
}
}
#Override
public void onFailure(Call<ContactsResponse> call, Throwable t) {}
});
In your Fragment class, create a data member of type boolean like,
private boolean isResponseSend;
In your onResume() method,
#Override
public void onResume() {
super.onResume();
if(!isResponseSend)
{
isResponseSend = true;
//your code
FactoryAPI.getContacts().getContacts(user.getToken()).enqueue(new Callback<ContactsResponse>() {
#Override
public void onResponse(Call<ContactsResponse> call, Response<ContactsResponse> response) {
if(response.isSuccessful()) {
contactList = response.body().getContactsList();
sortList();
progressDialog.dismiss();
setRecyclerView();
}
}
#Override
public void onFailure(Call<ContactsResponse> call, Throwable t) {}
});
}
}
According to
https://developer.android.com/guide/components/fragments.html#Creating
you can post the request on
https://developer.android.com/reference/android/app/Fragment.html#onAttach(android.content.Context)
Use some variable like flag, and initialise it in the onCreate. and based on the flag, you can handle the request.