I have a listview and I'm loading dynamically items into it.
The problem is when I'm activating that activity. It takes too long, so I have to show some progress dialog while loading the UI.
I really don't know how to do it, since doInBackground (If using Async task) doesn't allow the developer to mess with the UI.
What should I do ?
Here is my UI load code :
LeagueTableRow leagueTableRow_data[] = new LeagueTableRow[]
{
new LeagueTableRow(1,R.drawable.logo,"aaa",12,9,3,14),
new LeagueTableRow(3,R.drawable.logo,"aaa",12,9,3,14),
new LeagueTableRow(4,R.drawable.logo,"aaa",12,9,3,14),
new LeagueTableRow(5,R.drawable.logo,"aaa",12,9,3,14),
new LeagueTableRow(2,R.drawable.logo,"aaa",12,9,3,14)
};
LeagueTableRowAdapter adapter = new LeagueTableRowAdapter(context,
R.layout.leaguetablecontent, leagueTableRow_data);
listViewLeagueTable = (ListView)findViewById(R.id.listViewLeagueTable);
View header = (View)getLayoutInflater().inflate(R.layout.leaguetableheader, null);
listViewLeagueTable.addHeaderView(header);
listViewLeagueTable.setAdapter(adapter);
That can be achieved with the help of AsyncTask (an intelligent backround thread) and ProgressDialog
A ProgressDialog with indeterminate state would be raised when the AsyncTask starts, and the dialog is would be dismissed once the task is finished .
Example code
What the adapter does in this example is not important, more important to understand that you need to use AsyncTask to display a dialog for the progress.
private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected ContactsListCursorAdapter doInBackground(Void... params) {
cur1 = objItem.getContacts();
startManagingCursor(cur1);
adapter1 = new ContactsListCursorAdapter (viewContacts.this,
R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});
return adapter1;
}
protected void onPostExecute(ContactsListCursorAdapter result) {
list.setAdapter(result);
dialog.dismiss();
}
}
If you set the emptyview using listView.setEmptyView . The view will show in the place of list until you do a setadapter on the list. So As soon as you do setAdapter the emptyview will disappear. You can pass Progressbar to the setEmptyview in your case to show the progressbar.
Edit:
Use Setadapter in OnPostExecute of the Asynctask.
OnPostExecute, OnPreExecute, OnProgressUpdate, OnCancelled all run on UI thread. If you still insist on ProgressDialog, then create dialog in OnPreExecute and dismiss it in OnpostExecute and OnCancelled of the Asynctask
Please use AsyncTask if loading of list is taking too much time.Place a progress bar on the top of list view use that in AsyncTask.Hope this will help you
Related
i'm trying to add a indeterminate progressDialog to my UI once i click a list element that calls a AsyncTask, but unfortunately, if I call the dialog on the onPreExecute like this:
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog.setProgressStyle(R.style.AppTheme_Dark_Dialog);
dialog.setIndeterminate(true);
dialog.setMessage(activity.getString(R.string.Buscando));
dialog.show();
}
Obs: Worth noting that the Async is not a subClass of the Activity Class, i'm passing the activity as a parameter to the constructor.
and
#Override
protected void onPostExecute(BuscaPendentesFechamento buscaPendentesFechamento) {
super.onPostExecute(buscaPendentesFechamento);
if(dialog.isShowing())
dialog.dismiss();
}
the dialog simply doesn't show at all, although it is created and called(alredy checked, the activity instance is correct)
and if I set the dialog on the activity itself, like:
final ProgressDialog progressDialog = new ProgressDialog(RegistraPeso.this, R.style.AppTheme_Dark_Dialog);
progressDialog.setIndeterminate(true);
progressDialog.setMessage(getString(R.string.Buscando));
progressDialog.show();
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(getApplicationContext());
response = exportProjectRequisition.execute(nomeEquip,RegistraPeso.this);
progressDialog.dismiss();
the Dialog shows on the Ui, but only after the AsyncTask alredy performed, and not before it is called, and according to the code, it should be showing before the Async even gets created.
What can I do? What am I doing wrong? Please help.
Edit: Added where the Dialog is created:
private ProgressDialog dialog;
private RegistraPeso activity;
BuscaPendentesFechamento(RegistraPeso activity) {
this.dialog = new ProgressDialog(activity);
this.activity = activity;
}
Edit: Added the doInBackground:
#Override
protected BuscaPendentesFechamento doInBackground(String... params) {
ArrayList<UmData> jsonArrayResponse = JSONParser.makeHttpRequestArray(
Constants.URL_PENDENTES_FECHAMENTO,
Constants.METHOD_POST, requisition.writeJSON(params[0]),
requisition.getContext());
if(jsonArrayResponse!=null)
requisition.setJsonArrayResponse(jsonArrayResponse);
else {
UmData umData = new UmData();
umData.setItemUm("Server not responding");
jsonArrayResponse = new ArrayList<>();
jsonArrayResponse.add(umData);
requisition.setJsonArrayResponse(jsonArrayResponse);
}
return requisition;
}
Application context would not work in this case . Replace line below
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(getApplicationContext());
To
BuscaPendentesFechamento exportProjectRequisition = new BuscaPendentesFechamento(YourActivity.this);
I see your code you are calling dismiss() just after execute(). Remove this line.
progressDialog.dismiss();
OP here, the problem was solved by changing the code based on [this][1]
[1]: How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class? post here, sent to me by #MikeM, The problem was that I was getting the response using the .get() from the AsyncTask, and it was transforming the Async into a Syncronous Task.
Thanks for the support Mike!
I have a button, and when I clicked on it, I load other Activity, onCreate of this I call a method that fills a spinner with data from a Web Service.
Well, When I click at this button the screen stay "frozen" and then shows the Activity. So, I thought that it could be a good thing shows a progress dialog for user, and after gets the return of the Web Service, ends the progress dialog.
I tried use Handler, and now I'm trying to use AsyncTask, but, geting NullPointerException, because my program is filling spinner before web service get called.
private void fillSpinner(){
//runWebService();
new CallWebServiceAsyncTask().execute(null);
mAdapter = new PlanesAdapter(this, allPlanes);
mList.setAdapter(mAdapter);
}
class CallWebServiceAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progressDialog;
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(PlanesActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.show();
}
#Override
protected Void doInBackground(Void... v) {
runWebService();
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
because my program is filling spinner before web service get called.
you should fill data after getting data in onPostExecute Method
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
mAdapter = new PlanesAdapter(this, allPlanes);
mList.setAdapter(mAdapter);
}
What #SamirMangroliya suggested is correct but you even need to know where you are going wrong. When you call an AsyncTask you are asking the application to do some actions in the background which will take place in the non-UI thread. Now when you call execute() on your AsyncTask object the application code written in the function doInBackground(Void... v) runs in background and your control returns to the next statement following the call to execute() [new CallWebServiceAsyncTask().execute(null)], which in your case is the action of filling the adapter values. These values are yet to be received from the webservice. The only place where you can be sure that your background action is completed is the function onPostExecute(Void result) where as suggested you can create your adapter.
I am attempting to use AsyncTask to load a file of determinate length. My AsyncTask looks something like this:
protected void onPreExecute() {
dialog = ProgressDialog.show(MyActivity.this, null, "Loading", false);
}
protected void onProgressUpdate(Integer... values) {
if (values.length == 2) {
dialog.setProgress(values[0]);
dialog.setMax(values[1]);
}
}
in my doInBackground() implementation I call publishProgress(bytesSoFar, maxBytes); inside my loading loop and in the onPostExecute() I call dialog.dismiss().
However, I can't get the ProgressDialog to show anything but an indeterminate spinner. I want to see a horizontal progress bar that shows the progress as the loading happens. I've debugged and can see that onProgressUpdate() gets called with sane values and that the dialog's methods are getting called.
Add Style to your progress dialog with before you show it .setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
Use this code in your onPreExecute().
ProgressDialog prog;
prog = new ProgressDialog(ctx);
prog.setTitle(title);
prog.setMessage(msg);
prog.setIndeterminate(false);
prog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
prog.show();
I have some data I load into the database the first time a user enters my Activity, and want to show a ProgressDialog while this data is loaded for the first time. My Activity is an ExpandableListActivity and I don't create the SimpleExpandableListAdapter or call setListAdapter passing my adapter until I'm sure the data is actually there. My onCreate looks like this:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mCategoryDbHelper = new CategoryDBHelper(this);
// Build default categories... if not there yet
CategoryDbBuilder builder = new CategoryDbBuilder(this);
if (!builder.hasCategoriesInTable()) {
showDialog(PROGRESS_DIALOG_ID);
builder.fillDbWithDefaultCategories();
removeDialog(PROGRESS_DIALOG_ID);
}
populate();
}
I've overwritten onCreateDialog as such:
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case PROGRESS_DIALOG_ID: {
ProgressDialog dialog = new ProgressDialog(this);
dialog.setMessage("Loading categories for the first time. Please wait...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
return dialog;
}
}
return null;
}
The populate() method reads the database and sets up my list adapter, then calls setListAdapter.
This seems like it should be simple, but it's turning out to be a huge pain. Any help would be appreciated. :-)
Use AsynTask put your database loading processing in background function and in post execution display result. and there is another function to processing something until background process running here is example of asynTask
Android - I want to show file upload progress to the user
Just use this simple line:
mProgressDialog = ProgressDialog.show(context, "", "msg to show", true);
You can dismiss it with:
mProgressDialog.dismiss();
I've got an Android activity which grabs an RSS feed from a URL, and uses the SAX parser to stick each item from the XML into an array. This all works fine but, as expected, takes a bit of time, so I want to use AsyncActivity to do it in the background. My code is as follows:
class AddTask extends AsyncTask<Void, Item, Void> {
protected void onPreExecute() {
pDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Retrieving data ...", true);
}
protected Void doInBackground(Void... unused) {
items = parser.getItems();
for (Item it : items) {
publishProgress(it);
}
return(null);
}
protected void onProgressUpdate(Item... item) {
adapter.add(item[0]);
}
protected void onPostExecute(Void unused) {
pDialog.dismiss();
}
}
Which I call in onCreate() with
new AddTask().execute();
The line items = parser.getItems() works fine - items being the arraylist containing each item from the XML. The problem I'm facing is that on starting the activity, the ProgressDialog which i create in onPreExecute() isn't displayed until after the doInBackground() method has finished. i.e. I get a black screen, a long pause, then a completely populated list with the items in. Why is this happening? Why isn't the UI drawing, the ProgressDialog showing, the parser getting the items and incrementally adding them to the list, then the ProgressDialog dismissing?
I suspect something is blocking your UI thread after you execute the task. For example, I have seen folks do things like this:
MyTask myTask = new MyTask();
TaskParams params = new TaskParams();
myTask.execute(params);
myTask.get(5000, TimeUnit.MILLISECONDS);
The get invocation here is going to block the UI thread (which presumably is spinning off the task here...) which will prevent any UI related stuff in your task's onPreExecute() method until the task actually completes. Whoops! Hope this helps.
This works for me
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
It is because you used AsyncTask.get() that blocks the UI thread "Waits if necessary for the computation to complete, and then retrieves its result.".
The right way to do it is to pass Activity instance to your AsyncTask by constructor, and finish whatever you want to do in AsyncTask.onPostExecution().
If you subclass the AsyncTask in your actual Activity, you can use the onPostExecute method to assign the result of the background work to a member of your calling class.
The result is passed as a parameter in this method, if specified as the third generic type.
This way, your UI Thread won't be blocked as mentioned above. You have to take care of any subsequent usage of the result outside the subclass though, as the background thread could still be running and your member wouldn't have the new value.