Below is my code and I get the data from the webservice(remote server) in the doinbackground(). I want to set the data on the UI. Everything works fine. But as I have huge amount of data to be retrieved from the server, the progress bar is showing for a long time. So, I decided to use something like CW endlesss adapter or according to this. It's been giving me grief for few days by now.
1) CW endless adapter: I face a lot of problems in including it as a library project and when I try to run demos, it always shows me ! symbol in red color. When I click on run, it says your project has errors, but there is not even a single clue where does that error occur. Even I am unable to understand the things that have to be done too as those are somewhat difficult for me as a beginner. So, I decided to follow as per the other.
2) In this, I am unable to get on how to use this in my scenario as I am getting the data as a whole after completion of the doInBackground().
Can someone help me on this with relevant code snippets? I would be very thankful for your help.
I am calling this asynctask in onCreate() method.
class LoadAllData extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(GetData.this);
pDialog.setMessage("Loading Data. Please wait...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting All Data from url
* */
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("datatobefetched", datadetails));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_ads, "POST", params);
Log.d("All Products: ", json.toString());
try {
// Checking for SUCCESS TAG
int check = json.getInt(CHECK);
if (Check == 1) {
// Data found
// Getting Array of Data
dataJsonArray = json.getJSONArray("totaldata");
// looping through All data
for (int i = 0; i < dataJsonArray.length(); i++) {
JSONObject jobj = dataJsonArray.getJSONObject(i);
// Storing each json item in variable
String id = jobj.getString("rowid");
String product = jobj.getString("data1");
String review = c.getString("data2");
String imagepath = c.getString("image_url");
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put("id", id);
map.put("product", product);
map.put("review", review);
map.put("imageurl", imagepath);
// adding map to ArrayList
productsList.add(map); // ProductList is arrayList.
}
}
else {
// no data found
}
}
catch (JSONException e) {
e.printStackTrace();
}
return null;
}
/**
* After completing background task Dismissing the progress dialog
* **/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
// Updating parsed JSON data into ListView
// Getting adapter by passing xml data ArrayList
ListView list = (ListView)findViewById(R.id.list);
adapter = new CustomListAdapter(GetAllAds.this, productsList, passedcategory);
list.setAdapter(adapter);
}
});
}
}
with the code you posted there doesn't seem to have anything that would be taking an awful a lot of time.
I don't believe making an endless list (either using the endless adapter or manually) is the case for you because apparently the web-server you're communicating with does not have the options for page (e.g. when on the URL you specific items per page and page number like this: ?per_page=20&page_no=1) and those type of list only makes sense for such.
Just as a simple test, put those lines before after your code:
long now = System.currentTimeMillis();
JSONObject json = jParser.makeHttpRequest(url_all_ads, "POST", params);
Log.d("Test", "Elapsed time is: " + Long.toString(System.currentTimeMillis() - now));
then you can check on your LogCat how long did it took to make the http request.
edit:
suggested alternative to HashMap<> as I don't believe they are very efficient ways of storing data.
public class MyData(){
JSONObject data;
public MyData(JSONObject data){ this.data=data; }
public String getId(){ return data.getString("rowid"); }
// repeat for the other info you need, also override the toString to return the data.toString();
}
that way all the JSON parsing will be done at a later point in time and in small batches and your for loop would be as simple as:
for (int i = 0; i < dataJsonArray.length(); i++) {
productList.add(new MyData(dataJsonArray.getJSONObject(i));
}
Related
i have generated an app over e-commerce site (magento 2) while i am trying to startup my app it processing very slowly because of many products in my server is there any possible way to speed up my usage of Async task while using JSON feeds.. Please let me for any possible ways
My one of the AsyncTask coding:
private class GetProduct extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
// Showing progress dialog
dialog_pro = new ProgressDialog(Healthy_Cat.this);
dialog_pro.setMessage("Please wait...");
dialog_pro.setCancelable(false);
dialog_pro.show();
}
#Override
protected Void doInBackground(Void... arg0) {
HttpHandler sh = new HttpHandler();
String jsonStr = sh.makeServiceCall(url);
if (jsonStr != null) {
try {
JSONArray items = new JSONArray(jsonStr);
for (int i = 0; i < items.length(); i++) {
JSONObject c = items.getJSONObject(i);
pro_name = c.getString("name");
String price = c.getString("price");
JSONArray array = c.getJSONArray("custom_attributes");
for (int k = 0; k < array.length(); k++) {
JSONObject jb = array.getJSONObject(k);
String attr = jb.getString("attribute_code");
if (attr.equalsIgnoreCase("special_price")) {
splprice = jb.getString("value");
}
}
String sku = c.getString("sku");
JSONArray media = c.getJSONArray("media_gallery_entries");
for(int k = 0; k < media.length(); k++) {
JSONObject jb = media.getJSONObject(k);
String imageURL = BaseURL_Helper.MediaBase +jb.getString("file");
media_image = imageURL;
// tmp hash map for single contact
Beanclass dataSet = new Beanclass();
dataSet.setTitle(pro_name);
dataSet.setImage(imageURL);
dataSet.setPrice(price);
dataSet.setSPLPrice(splprice);
dataSet.setSku(sku);
list.add(dataSet);
BeanclassList data = new BeanclassList();
data.setTitle(pro_name);
data.setImage(imageURL);
data.setSku(sku);
data.setSPLPrice(splprice);
data.setPrice(price);
listbean.add(data);
}
}
}catch (final JSONException e) {
runOnUiThread(new Runnable() {
#Override
public void run() {
no_list.setVisibility(View.VISIBLE);
}
});
}
} else {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"May be Network error!!",
Toast.LENGTH_LONG)
.show();
}
});
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// Dismiss the progress dialog
/**
* Updating parsed JSON data into ListView
* */
if (dialog_pro.isShowing())
dialog_pro.dismiss();
mAdapter = new GridviewAdapter(Healthy_Cat.this,list);
gridlist.setAdapter(mAdapter);
Listadapter = new ListviewAdapter(Healthy_Cat.this,listbean);
listview_pro.setAdapter(Listadapter);
}
}
Thank u in advance..
There are few things you need to update in your code
API Calling lib: I'm using Retrofit for api calling very fast & simple to use. Support Header & Response caching too.
JSON Parsing: You are parsing JSON manually which is a time-consuming process. I'm using Google's JSON parsing Lib Gson. really very fast.
Pagination: If you having lots of data on the server then try to fetch data in small no of pieces. For example in case of "Item Listing API" try to fetch data from the server for 10-15 item at a time rather all the item at a once.
Asyntask performance speed is too low compare to Retrofit.
So For e-commerce app, You must use Retrofit.
There are a few things you can do. For starters, you don't have to parse the whole json, before updating view.
But really you yourself state the issue, which is you have too much data. This is not only a programming issue, it is also a user experience issue, too much data is confusing, especially on a mobile device.
What I suggest is breaking down your data into categories or the like. When app starts, download just a list of categories to display. Upon user choosing a category, then you download the data for that category.
When you download data, do it in chunks, so that you can start displaying right away.
There are many similar ideas that you can implement, for a better user experience.
Sorry for my bad english, but i have problem and can't figure it out..
I have custom listview in my fragment for getting products from JSON array. And I have 3 ImageButtons in every listview row;
Plus Button(+), Minus Button(-) and Remove Button(X)..
So when i click each button, its calling JSON request for update product's piece number, getting new datas from response and repopulate array list.
Everything ok but, when I click that buttons faster, it seems there is 1 sec delay between multiple requests even first volley request has already done before.
Here is my JSON method in TableAdapter.java
public void JSON(final int position, final int process) {
if (inProgress==false) {
dialog = new ProgressDialog(myContext);
dialog.setMessage("Updating.....");
dialog.show();
inProgress = true;
System.out.println("**** Now request is beginning............");
final int rowID = tableModelList.get(position).getID();
final int treeID = tableModelList.get(position).getAna_dal();
final float price = tableModelList.get(position).getBFiyat();
final int quantity = tableModelList.get(position).getAdet();
final int print = tableModelList.get(position).getYazdimi();
final String insertUrl = "http://"+getServer+"/t6mobilservice/order-piece.php";
Map<String, String> parameters = new HashMap<>();
parameters.put("tableID", "" + getTableId);
parameters.put("rowID", "" + rowID);
parameters.put("treeID", ""+treeID);
parameters.put("process",""+process);
parameters.put("quantity",""+quantity);
parameters.put("price",""+price);
parameters.put("print",""+print);
CustomRequest jsObjRequest = new CustomRequest(Request.Method.POST, insertUrl, parameters, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray getOrders = response.getJSONArray("order");
Gson gson = new Gson();
tableModelList.clear();
for (int i = 0; i < getOrders.length(); i++) {
JSONObject order = getOrders.getJSONObject(i);
TableModel tableModel = gson.fromJson(order.toString(), TableModel.class);
tableModelList.add(tableModel);
}
mAdapter.notifyDataSetChanged();
System.out.println("**** onResponse: Request is done............");
System.out.println("**** JSON: "+response.toString());
dialog.cancel();
inProgress = false;
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError response) {
Log.d("Response: ", response.toString());
inProgress = false;
}
});
requestQueue.add(jsObjRequest);
}
}
Dialog is showing when request beginning and canceling when request is done. But as I said, when I click faster, there is a delay between multiple requests even first request has already done. I'm saying 1 sec, because 2nd request is beginning after 1 sec exactly, no matter how I clicking fast. I can't figure it out..
I tested fast clicks to showing toasts with random numbers and it's working fine. But when I testing with JSON method, there is a weird delay.
I have SwipeRefreshLayout and ScrollView in my fragment.
I'm using Volley with singleton.
EDIT 1. : Here's a video link to showing what my problem is..
EDIT 2. : Here's a LogCat output video for every click
Every fast click has returning success json output, but nothing change instantly..
Thanks for your help.
Im trying to dynamicly load listview.
Firstly,getting first ten data from web serives and adding it to listview.
For every ten row proggress dialog should appear when getting data.
If I dont use dismis, proggres dialog appear.
If I use dismis, proggresbar does not appear or appear and dismissed never shown in screen.
While getting response from web services screen stucks for 1-2 sec. It should not be.
Here is my code
public void setMessageList(int rowsArea){
ProgressDialog progressDialog = ProgressDialog.show(AdminMessages.this, "", "Loading...");
progressDialog.getWindow().setGravity(Gravity.BOTTOM);
List<NameValuePair> parameter = new ArrayList<NameValuePair>();
String url_confirmation =getInstance.getInstance().getUrl()+"getspecificrowmessages.php";
parameter.add(new BasicNameValuePair("rowsarea", Integer.toString(rowsArea)));
JSONObject json = jsonParser.makeHttpRequest(url_confirmation,"POST", parameter);
try {
int success = json.getInt("result");
if(success == 1) {
JSONArray messages = json.getJSONArray("messages");
for(int i=0;i<messages.length();i++){
JSONObject c = messages.getJSONObject(i);
String subject=c.getString("theSubject");
Integer id=c.getInt("id");
Integer msgId=c.getInt("msgId");
String senderName=c.getString("sender_name");
String receiverName=c.getString("recipient_name");
String dateTime=c.getString("dateTime");
String theFileNames=c.getString("theFileNames");
messageDetailList.add(new MessageListDetail(subject,senderName,receiverName,dateTime,theFileNames,id,msgId));
}
page+=10;
}
progressDialog.dismiss();
}
catch (JSONException e) {
e.printStackTrace();
}
}
The reason is that you should use a ProgressBar instead, and manage its visibility with setVisibility(View.VISIBLE) for showing it, and setVisibility(View.GONE) for hiding it.
my app receive a jsonArray that have names of categories and their images urls.
so i want to extract the names and also download the image by they urls.
actually i succeed to extract the names and also the urls, look at the code bellow:
private class ReadPlacesFeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
return readJSONFeed(urls[0]);
}
protected void onPostExecute(String result) {
try {
JSONObject jsonobject = new JSONObject(result);
JSONArray categories = new JSONArray(
jsonobject.getString("categories"));
for (int i = 0; i < categories.length(); i++) {
JSONObject category = categories.getJSONObject(i);
names.add(category.getString("name"));
images.add(category.getString("image"));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
getBaseContext(), R.layout.row_channel_layout,
R.id.channel_name, names);
channel_list = (ListView) findViewById(R.id.channel_list);
channel_list.setAdapter(adapter);
}
}
my questions:
1. is it ok to build the adapter in the onPostExecute method ?
2.should i write another a synctasck class to download the images?,or extract the urls in doInbackground method and after that download the images, and return both of the images and the names to onPostExecute method.
actually i try this and i think it is very slow because decoding the json in the background method is very slow !
3.how could i build the listView after downloading the names, then after downloading the images, i just modify it.
thank you
1: Typically yes, though your better to make the adapter then pass the values to it on the post execute then call adapter.NotifyDataSetChanged();
2: I recommend not reinventing the wheel and using the "fantastic" picasso image loading library
http://square.github.io/picasso/
3: Create one listview, pass the names and urls to it, make the array adapter into your own custom e.g. "myListAdapter" which then sets the name value and then using picasso download and load the image into your imageview or whatever else you want to do with it.
http://www.vogella.com/tutorials/AndroidListView/article.html#adapterown_custom
E.g.
public class MainActivity extends Activity
{
ArrayList<String> myListItems = new ArrayList<String>();
ArrayAdapter<String> adapter;
#Override
protected void onCreate(Bundle savedInstanceState)
{
adapter = new ArrayAdapter(this,R.layout.row_category_layout,R.id.category_name, names);
//execute my data task
}
public void dataTask()
{
//GOT SOME DATA
myListItems.add("MYDATA");
adapter.notifyDataSetChanged();
}
I want to show Facebook Page's Notes items with those comments and likes using Graph API.
To do that, I'm using the asyncFacebookRunner in Facebook SDK.
Steps are like this:
call asyncFacebookRunner.request to get Note Item with PageId
mAsyncRunner.request(sAPIString, new NotesRequestListener(), null);
Response has come. ( I can't highlight function call. Sorry for inconvenient to find it.)
public class NotesRequestListener implements com.facebook.android.AsyncFacebookRunner.RequestListener
{
/**
* Called when the request to get notes items has been completed.
* Retrieve and parse and display the JSON stream.
*/
#Override
public void onComplete(String response, Object state) {
// TODO Auto-generated method stub
Log.i("My_TAG", "onComplete with response, state");
try
{
// process the response here: executed in background thread
final JSONObject json = new JSONObject(response);
JSONArray arrNotesItems = json.getJSONArray("data");
int l = (arrNotesItems != null ? arrNotesItems.length() : 0);
// !!!!
// This has another request call
// !!!!
final ArrayList<WordsItem> newItems = WordsItem.getWordsItems(arrNotesItems,getActivity());
WordsActivity.this.runOnUiThread(new Runnable() {
public void run() {
wordsItems.clear();
wordsItems.addAll(newItems);
aa.notifyDataSetChanged();
}
}); // runOnUiThread
} // try
catch (JSONException e)
{
Log.i("My_TAG", "JSON Error in response");
} // catch
} // onComplete
... other override methods ...
} // Request Listener
< Another Class >
public static ArrayList<WordsItem> getWordsItems(JSONArray arrJSON, Activity activity) {
ArrayList<WordsItem> wordsItems = new ArrayList<WordsItem>();
int l = (arrJSON != null ? arrJSON.length() : 0);
try {
WordsItem newItem;
for (int i=0; i<l; i++) {
JSONObject jsonObj = arrJSON.getJSONObject(i);
String sTitle = jsonObj.getString("subject");
String sNoteID = jsonObj.getString("id");
... get another fields here ...
newItem = new WordItem(...);
// !!!!
// This has request call for comments
// !!!!
ArrayList<CommentItem> arrComment = getUserComments(sNoteID);
wordsItems.add(newItem);
}
} catch (Exception e) {
e.printStackTrace();
}
return wordsItems;
} // getWordsItems
call another asyncFacebookRunner.request to get comments of item(with NoteID)
in getUserComments
mAsyncRunner.request(sAPIString, new CommentRequestListener(), null);
Before getting comments(OnComplete in CommentRequestListener has not called), getWordsItems returns item array.
So I can't see the comments.
How can I wait to update UI till getting comments?
(It's so ironic to synchronize asynchronized calls.)
Thanks in advance.
Use facebook object which has non-asynchronous request method.
You need not implement listener method.
So, I suggest below means.
use mAsyncRunner.request for first request call.
use mFacebookRunner.request for second request call.
I hope it may help you:-)
Using FQL - Facebook Query Language you can easily get all this information about any particular note info
, Also to get likes on that and comments over it as like examples given in the links.