How to dismiss dialog when calling retrofit multiple times? - android

I am using retrofit to access API with counter value, i.e. when I
getting first time response calling retrofit method again and again
till the last counter value.I also do after getting response download
image using AsyncTask.
When i first time calling the retrofit method, Showing Progress
Dialog. I want to dismiss dialog when last image downloaded.
visibleProgressBar(getString(R.string.fetch_data_msg));
getMyOxygenInitialSync();
public void getMyOxygenInitialSync() {
if (new CheckConnection(context).isConnectedToInternet()) {
UserPreferences preferences = UserPreferences.getUserPreferences(context);
ApiInterface apiService = ApiClient.getClient().create(ApiInterface.class);
try {
JsonObject params = new JsonObject();
params.addProperty("my_oxygen_user_id", "984");
params.addProperty("action", "fullSync");
params.addProperty("page", String.valueOf(page));
params.addProperty("syncDate", "");
// RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"),(new JSONObject(params)).toString());
Call<MyOxygenSyncResponseMain> call = apiService.getMyOxygenSycList(params);
call.enqueue(new Callback<MyOxygenSyncResponseMain>() {
#Override
public void onResponse(Call<MyOxygenSyncResponseMain> call, retrofit2.Response<MyOxygenSyncResponseMain> response) {
invisibleProgressDialog();
try {
if (response != null) {
/* MyOxygenSyncResponseMain myOxygenSyncResponseMain = new MyOxygenSyncResponseMain();
myOxygenSyncResponseMain = ((MyOxygenSyncResponseMain)response);*/
totalPage = response.body().getTotalPage();
page++;
if (response.body().getImageDetail() != null && response.body().getImageDetail().size() > 0) {
for (int i = 0; i < response.body().getImageDetail().size(); i++) {
MyOxygen myOxygen = new MyOxygen();
myOxygen.setImageId(response.body().getImageDetail().get(i).getMy_oxygen_image_id());
myOxygen.setImageName(response.body().getImageDetail().get(i).getMy_oxygen_image_name());
myOxygen.setImagePhysicalPath(response.body().getImageDetail().get(i).getMy_oxygen_image_url());
myOxygen.setCategory(response.body().getImageDetail().get(i).getMy_oxygen_image_cat());
myOxygen.setSyncDate(response.body().getImageDetail().get(i).getSyncDate());
// myOxygen.setOrderId(myOxygenSyncResponseMain.getImageDetail().get(i).getOrde());
myOxygen.setIsUpdated(Integer.parseInt(response.body().getImageDetail().get(i).getMy_oxygen_is_deleted()) == 0 ? 1 : 0);
myOxygen.setIsDeleted(response.body().getImageDetail().get(i).getMy_oxygen_is_deleted());
myOxygenDBHelpher.saveMyOxygen(myOxygen);
downloadImage(myOxygen.getImageName(),myOxygen.getImagePhysicalPath(),myOxygen.getImageId());
}
for(page=page;page<=totalPage+1;page++){
getMyOxygenInitialSync();
}
/* if( page== totalPage){
downloadImage();
}*/
}
Log.d("Resp ", response.raw().body().toString());
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<MyOxygenSyncResponseMain> call, Throwable t) {
invisibleProgressDialog();
try {
Log.d("Error ", call.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
}

Related

Retrofit - how do I make a synchronous request within an asynchronous request

I'm implementing a two-level nested recyclerView and both recycler views make an API call using retrofit. This is the method that makes the synchronous request:
public void loadSectionStories(String sessionKey, CuratedSection section) {
Call<JsonArray> subCall;
subCall = TravelersApi.endpoint().getCuratedSectionTopics(sessionKey, section.id);
try {
Response<JsonArray> response = subCall.execute();
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawStories = response.body();
if(rawStories.size() == 0) {
//TODO: show placeholder
return;
}
ArrayList<CuratedSectionItem> stories = new ArrayList<>();
for(int i = 0; i < rawStories.size(); i++) {
JsonObject jStories = rawStories.get(i).getAsJsonObject();
JSONObject temp = new JSONObject(jStories.toString());
JsonObject author = jStories.get("author").getAsJsonObject();
CuratedSectionItem story = new CuratedSectionItem();
story.title = jStories.get("title").getAsString();
story.avatar = author.get("profile_photo").getAsString();
story.displayPhoto = temp.getString("primary_photo");
story.username = author.get("username").getAsString();
story.description = jStories.get("content").getAsString();
story.topicId = jStories.get("id").getAsString();
story.postId = jStories.get("first_post_id").getAsString();
story.hasReacted = false;
story.upvotes = jStories.get("stats").getAsJsonObject().get("upvotes").getAsInt();
stories.add(story);
}
section.stories = stories;
} catch (IOException e) {
Log.d("ERROR!", e.toString());
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
This is the method that makes the asynchronous request and also calls loadSectionStories in a thread:
public void loadCuratedSections(final int start, final int limit) {
SharedPreferences prefs = getSharedPreferences("user_session", MODE_PRIVATE);
final String sessionKey = prefs.getString("session_key", null);
Call<JsonArray> call;
call = TravelersApi.endpoint().getCuratedSections(sessionKey);
call.enqueue(new Callback<JsonArray>() {
#Override
public void onResponse(Call<JsonArray> call, Response<JsonArray> response) {
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawSections = response.body();
if(rawSections.size() == 0) {
return;
}
for (int i = start; i < limit; i++) {
JsonObject jSection = rawSections.get(i).getAsJsonObject();
final CuratedSection section = new CuratedSection();
section.id = jSection.get("id").getAsString();
section.header = jSection.get("section_header").getAsString();
section.isShown = jSection.get("is_shown").getAsBoolean();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
loadSectionStories(sessionKey, section);
}
});
thread.start();
curatedSections.add(section);
}
}
#Override
public void onFailure(Call<JsonArray> call, Throwable t) {
Log.d("ERROR!", t.toString());
t.printStackTrace();
}
});
}
Everything is working fine except the fact that section.stories returns null. It doesn't make sense to me because of this statement section.stories = stories inside loadSectionStories.
If you are using section.stories before your synchronous request is completed (which is running in new threads) then it will return null which is currently happening.
so either you have to remove new thread flow if you want to use it after your first asynchronous request is completed,
or you have to reload your recycler view when you stories is updated.
Also why are you executing your synchronous request(loadSectionStories) in new thread, is it not similar to asynchronous request?
Retrofit asyncRetrofit = new Retrofit.Builder()
.baseUrl(URLS.MAIN_SERVER_URL)
// below line create thread for syncrouns request
.callbackExecutor(Executors.newSingleThreadExecutor())
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
this will run your request in asyncronous

How to wait first for the retrofit response before returning the boolean

always returning the wrong value, before the request has been finish. The validation will already return the value without waiting for the response. I'am using retrofit for request then i put it on listener.
Thankyou for the help, suggestion is much accepted!.
this is my code, i have validation for the screen when it's true it will goes to another screen.
#Override
public boolean isValid() {
if (NetworkUtils.isConnected(getActivity())) {
final AtomicBoolean pass = new AtomicBoolean(false);
Thread simpleThread = new Thread() {
public void run() {
new ReprintOnlineHelper(rType, receiptNoEditText.getText().toString(), issuedDate, etTotalAmtPaid.getText().toString(), new ReprintOnlineHelper.ReceiptNoSearchListener() {
#Override
public boolean onServiceResponse(List<ReceiptNumber> receiptNumbers) {
Log.e("receiptNumbers", "" + receiptNumbers.get(0).getTPAYRECEIPTNO());
if (receiptNumbers.isEmpty()) {
returnValue = "eReceipt Number not found!";
val = true;
} else {
String pdates = null, ddates;
try {
if (!receiptNumbers.get(0).getTPAYISSUEDDATE().isEmpty()) {
Date periodFormat = df.parse(receiptNumbers.get(0).getTPAYISSUEDDATE());
pdates = sdf.format(periodFormat);
}
} catch (ParseException e) {
e.printStackTrace();
Log.e("ddd", "" + e.getMessage());
}
String tinNo = receiptNumbers.get(0).getTPTIN();
if (tinNo.contains("-")) {
tinNo = receiptNumbers.get(0).getTPTIN().replace("-", "");
}
Log.e("JAC", "" + receiptNumbers.get(0).getTPAYRECEIPTNO() + "---" + AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)) + "---" + MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) + "--" + AlfonzoUtils.formatDate(issuedDate) + "--" + receiptNoEditText.getText().toString() + "--" + tinNo + "--"+revenueCollection.getTpTin().replace("-", ""));
if (receiptNumbers.get(0).getTPAYRECEIPTNO().equals(receiptNoEditText.getText().toString()) &&
AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)).contentEquals(AlfonzoUtils.formatDate(issuedDate))
&& MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) == MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString()) && tinNo.equals(revenueCollection.getTpTin().replace("-", ""))) {
pass.set(true);
returnValue = "success";
val = true;
showMessagePrompt(rType,returnValue);
return true;
} else if (!tinNo.equals(revenueCollection.getTpTin().replace("-", ""))) {
returnValue = "eReceipt Number was not issued to this TIN " + revenueCollection.getTpTin();
val = false;
} else if (!AlfonzoUtils.formatDate(DateUtils.simpledateToMillis(pdates, DateUtils.DateFormat.SIMPLE_DATE_5_FORMAT)).contentEquals(AlfonzoUtils.formatDate(issuedDate))) {
returnValue = "Issued date is not valid";
val = false;
} else if (MoneyEditText.toDouble(receiptNumbers.get(0).getTOTALPAID()) != MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString())) {
returnValue = "Total amount paid is not valid";
val = false;
} else if (!receiptNumbers.get(0).getTPAYRECEIPTNO().equals(receiptNoEditText.getText().toString())) {
returnValue = "ReceiptNo is not valid";
val = false;
}
}
return false;
}
#Override
public void onErrorResponse(int err) {
}
}).reprintReceiptNo();
}
};
if (!receiptNoEditText.getText().toString().isEmpty() && issuedDate != 0 /*&& MoneyEditText2.toDouble(etTotalAmtPaid.getText().toString()) > 0*/) {
try {
simpleThread.start();
simpleThread.join();
pass.get();
Log.e("pass", "" + pass + "-" + pass.get() + val);
} catch (InterruptedException e) {
e.printStackTrace();
}
return pass.get();
}
}
return false;
}
this is my request in retrofit:
public void reprintReceiptNo() {
JSONObject jO = new JSONObject();
JSONObject result = new JSONObject();
JSONArray jsonArray = new JSONArray();
try {
jO.put("xReceipt", receiptTypeNo);
jO.put("xType", receipttype);
jsonArray.put(jO);
result.put("dataArray", jsonArray);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.e("dataArray", "----- " + result.toString());
ServiceInterface si = BaseRestClient.getClient();
Observable<List<ReceiptNumber>> call = si.getreprintReceiptNumber(result.toString());
call.subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<ReceiptNumber>>() {
#Override
public void onCompleted() {
}
#Override
public void onError(Throwable e) {
}
#Override
public void onNext(List<ReceiptNumber> receiptNumbers) {
Log.e("receiptNumbers", "" + receiptNumbers.toString());
onReceiptNoSearchListener.onServiceResponse(receiptNumbers);
}
});
}
Its not possible for the isValid() method to wait for the service reponse if you have code outside the Thread you've created.
The method will execute the Thread, but while that Thread is executing, the rest of the code will be read, meaning the return pass.get(); or the return false; statments will be read, causing the the method to return before the server response.
The solution its to change the way this was done. You should check if you can call the server and then created your logic in the methods onServiceResponse() and onErrorResponse() based on how you want to proceed.

eventbus inside recursive function

i am posting event using EventBus inside a recursive function that fetches pagination data from the webservice.
public void getCallsData(final UserRequest userRequest){
serviceCall.enqueue(new Callback<UserResponseInfo>() {
#Override
public void onResponse(Call<UserResponseInfo> call, Response<UserResponseInfo> response) {
if(response.isSuccessful()) {
UserResponseInfo userResponseInfo = response.body();
if (userResponseInfo != null) {
try {
Log.e(TAG, "getCallsData response " + LoganSquare.serialize(userResponseInfo));
} catch (IOException e) {
e.printStackTrace();
}
int currentPage = userRequest.getUserRequestInfo().get(0).getPage();
int totalPages = userResponseInfo.getTotalPages();
if(currentPage < totalPages){
userRequest.getUserRequestInfo().get(0).setPage(++currentPage);
Log.e(TAG, "getCallsData fetching next page "+currentPage);
userResponseInfo.setCurrentPage(currentPage);
userResponseInfo.setRequestType(GET_CALL_REQUEST);
EventBus.getDefault().postSticky(userResponseInfo);
getCallsData(userRequest);
}
} else {
}
}else{
}
}
#Override
public void onFailure(Call<UserResponseInfo> call, Throwable t) {
}
});
}
The issue is EventBus.getDefault().postSticky(userResponseInfo); when getCall executes in recursive fashion its not posting the event properly as in only first event is getting called and it misses the last one.

Progress dialog dismisses before the view is displayed in the gridview

I start my progress dialog in oncreate method of fragment before is initiate my web request call. In the web request call, if I fetch the response and if its success I call the notifydatasetchanged method to refresh the adapter . But the dialog gets dismissed lot before the view is updated . Please help .
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pd = ProgressDialog.show(getActivity(), "Loading...", "Please Wait...");
getProducts(highPrice, lowPrice, isLowtoHigh);
}
private void getProducts(String highPrice,String lowPrice,String isLowtoHigh) {
// loadingDialog.loading();
APIRequst.getProductsCategory(getActivity().getApplicationContext(), isLowtoHigh, lowPrice, highPrice, new APIRequestListner() {
#Override
public void onSuccess(String response) {
if (response == null || response.isEmpty()) {
Log.e("orderhistory", "success but empty");
} else {
Log.e("products", response);
try {
JSONObject mainObj = new JSONObject(response);
boolean result = mainObj.has("is_success") && mainObj.getBoolean("is_success");
String resultMessage = mainObj.getString("message");
if (resultMessage.equalsIgnoreCase("Success")) {
if (result) {
productItems.clear();
adptProductItems.clear();
JSONArray jsonOrderList = mainObj.has("categories") ? mainObj.getJSONArray("categories") : null;
if (jsonOrderList != null) {
for (int i = 0; i < jsonOrderList.length(); i++) {
JSONObject jsonObj = jsonOrderList.getJSONObject(i);
ProductListItem newItem = (new Gson()).fromJson(jsonObj.toString(), ProductListItem.class);
productItems.add(newItem);
}
adptProductItems.notifyDataSetChanged();
pd.dismiss();
}
}
} else {
if (resultMessage.equalsIgnoreCase("No Value")) {
if (pd.isShowing())
pd.dismiss();
productItems.clear();
adptProductItems.notifyDataSetChanged();
Toast.makeText(getActivity(), "Sorry no prducts to display", Toast.LENGTH_SHORT).show();
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
// adapter.notifyDataSetChanged();
}
#Override
public void onFailure() {
if (pd.isShowing())
pd.dismiss();
// loadingDialog.dismissDialog();
}
});
}
try to move " pd.dismiss();" below onFailure()
#Override
public void onFailure() {
if (pd.isShowing())
pd.dismiss();
// loadingDialog.dismissDialog();
}
pd.dismiss();
and
adptProductItems.notifyDataSetChanged();
//pd.dismiss(); remove fromhere
may it will help as I did in my case..

Why do i have a null pointer exception on database calls and what can i do to solve?

new AsyncTask<Ticket, Void, List<TPVLine>>() {
#Override
protected List<TPVLine> doInBackground(Ticket... params) {
List<TPVLine> lines;
while (true){
Log.d(TAG, "Waiting for data base response");
try {
lines = params[0].getLines();
Log.d(TAG, "Data base response completed");
break;
}catch (SQLiteException | NullPointerException ex){
ActiveAndroid.clearCache();
Log.d(TAG, "Cleaning cache");
Log.wtf(TAG, ex.toString());
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
return lines;
}
#Override
protected void onPostExecute(List<TPVLine> aVoid) {
super.onPostExecute(aVoid);
linesTPV = new ArrayList<TPVLine>();
if (aVoid != null){
linesTPV = aVoid;
}
linesTPV.addAll(noSavedLines);
mainActivity.getTpvFragment().resetPrice();
notifyDataSetChanged();
if (linesTPV.size() == 0){
mainActivity.getTpvFragment().getListContainer().setVisibility(View.INVISIBLE);
mainActivity.getTpvFragment().getMessageContainer().setVisibility(View.VISIBLE);
}else {
mainActivity.getTpvFragment().getListContainer().setVisibility(View.VISIBLE);
mainActivity.getTpvFragment().getMessageContainer().setVisibility(View.INVISIBLE);
}
notifyDataSetChanged();
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mainActivity.getCurrentTicket());
This are the calls, first in Ticket.java
public List<TPVLine> getLines() {
return new Select().from(TPVLine.class).where("Ticket = ?", this.getId()).execute();
}
The second is in TPVLine.java
public static List<TPVLine> getLines(Ticket ticket){
return new Select().from(TPVLine.class).where("Ticket = ?", ticket.getId()).orderBy("Id ASC").execute();
}
The issue is caused when i call TPVLine.class, i make sure first that Ticket != null. I'm using ActiveAndroid to manage the database
you are returning null instead of lines in your asynctask doInBackground event.
return lines;

Categories

Resources