I have read many solutions here to show a progress dialog on switching tabs as some of the tabs fetching data from server takes time in between that period i need to show progress dialog, do suggest where to put the code to accomplish my task
Initiate an Async which does the fetching data in the background and manages the progress dialog (or even progress layout which might be better) in the onprogressupdate method. If you subclass this it will be fairly easy to implement. Here's a link.
Add this
private class myAsyncTaskClass extends AsyncTask{
#Override
protected void onProgressUpdate(Object... values) {
// TODO Add updates to your progress dialog here.
super.onProgressUpdate(values);
}
#Override
protected Object doInBackground(Object... params) {
// TODO Add your fetching data here
//Use publish progress to call the onProgress update passing whatever you want.
publishProgress(values);
return null;
}}
Related
I have created a splash screen for my app to hide the periodic insertion (after publishing updates) of a large number of records into the different tables of my app's SQLite database. I have been implementing an AsyncTask to handle the insertion off of the UI thread.
I need to create a ProgressDialog (with progress bar, not the simple spinning wheel) to inform the user of the current progress percentage for the insertion operations.
In most examples for setting the dialog's progress bar, the counter variable for the for loop representing the lengthy operation, or the percentage of file download is used to set this progress for the dialog. However, since insertions into different tables may take different amounts of time (depending on number of columns, etc), this approach appears to fail. The closest solution I could see would be to write a publishProgress(some_percentage) line after every record insertion in my doInBackground() method, using the % of records inserted as the parameter for publishProgress(), but this seems like a terribly inelegant and inefficient practice.
The current code for my AsyncTask implementation is below. Any suggestions for the best practice of determining the current progress percentage would be greatly appreciated. Thanks!
private class InsertionAction extends AsyncTask<Void,Integer,Void> {
Context context;
private ProgressDialog dialog;
private ForwardAction(Context context) {
this.context = context;
dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
this.dialog.setMessage("Initializing Database. Please Wait...");
this.dialog.show();
this.dialog.getWindow().setGravity(Gravity.BOTTOM);
this.dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
this.dialog.setCancelable(false);
}
#Override
protected Void doInBackground(Void... params) {
// Large block of record insertions
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// Forward to the main activity
if (dialog.isShowing()) {
dialog.dismiss();
}
animatedTransition(SPLASH_DISPLAY_TIME/2);
}
#Override
protected void onProgressUpdate(Integer... values) {
}
}
Unfortunately there is no way to programmatically count your lines of code, calculate how much time they need to execute and generate an accurate time-proportionate progress.
I suggest updating the progress bar after a certain interval of lines, e.g. every 90 inserts (10%).
Or update according to what you are doing and modify the progress message (try to be creative), e.g. "Adding users", "Generating death rays", "Creating the universe", "Just a little longer", etc.
I have four Tab at the top of my apps
The content of the fourth tab is that it will get data from sql server and then display in listview
since the amount of data retrieved is quite big, it takes 2-3 sec
The problem is that:
After I click the fourth tab, it has no response, then after 2-3sec, it displays the content
As I know it is loading the data from database, I will not continue to click
However, when users click it and no response, he may click and click and click
How to show something to user so that they know it is loading data??
You should use a CrusorLoader. This will display a loading circle while still making the UI active. Note that even if you're using lower versions of the android API, you can still access the CursorLoader class via the Android Support Package. For more information on loaders, checkout
new SomeTask(0).execute(); // write this line in your 4th tab onCreate()
/** Inner class for implementing progress bar before fetching data **/
private class SomeTask extends AsyncTask<Void, Void, Integer>
{
private ProgressDialog Dialog = new ProgressDialog(yourActivityClass.this);
#Override
protected void onPreExecute()
{
Dialog.setMessage("loading...");
Dialog.show();
}
#Override
protected Integer doInBackground(Void... params)
{
//Task for doing something
// get data from sql server and then display in listview
return 0;
}
#Override
protected void onPostExecute(Integer result)
{
if(result==0)
{
//do some thing if your list completed
}
// after completed finished the progressbar
Dialog.dismiss();
}
}
When a long-running process is started, you'll want to indicate that something is happening so the user knows to wait. You want a progress dialog.
Here is an example:
http://www.androidpeople.com/android-progress-dialog-example
I am using a TabActivity with 4 separate Activities - one for each tab.
One of the Activities is a ListView that has a custom ArrayAdapter.
The issue is that when I press the Tab to change to this view, the Activity loads the content in before the view changes, this appears as though nothing happens for a couple of seconds until the xml is loaded and parsed etc.
I have looked for an example but this is my first Android appllication and I am having difficulty in understanding the flow.
Can anyone point me to some code that will allow me to instantly change the view (I can inform user content is loading) while loading the content in the background thread
thank you
EDIT - I am porting code over from an existing iOS app - I wasn't able to better articulate the problem as I didn't realise how the UI thread could be blocked in this situation, and due to the complexity of the existing code and deadline I didn't want to change the structure too much.
I narrowed down the issue before I saw your code Jennifer but it is the solution I used so Ill mark yours as right.
here is what I used if it helps anyone else, I had to put the function I called to trigger the data load onto a background thread and then display the content when that thread had done its work
This class was declared within my
public class TableView extends ListActivity
Which was hard for me to get my head around having not done this before ;)
public class GetContentTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog pdialog;
#Override
protected void onPreExecute(){
super.onPreExecute();
pdialog = new ProgressDialog(TableView.this);
pdialog.setTitle(progressDialogTitle);
pdialog.setMessage(progressDialogMessage);
pdialog.show();
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
setUpAndLoadList(); // the function to display the list and fill it with content
pdialog.dismiss();
}
#Override
protected Void doInBackground(Void... params) {
doInitialLoad(); // The function to load any xml data from server
return null;
}
}
You can use a progress Dialog (can inform user content is loading)
ProgressDialog dialog;
private class XMLOperation extends AsyncTask<String, Void, String> {
/*
* (non-Javadoc)
*
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
System.out.println("onPreExecute");
dialog= ProgressDialog.show(mContext, "", "Loading Content....");
dialog.setCancelable(false);
}
#Override
protected String doInBackground(String... urls) {
//do your Background task
}
protected void onPostExecute(String result) { //dismiss dialog
try {
if(dialog.isShowing()){
dialog.dismiss();
}
} catch (Exception exception) {
dialog.dismiss();
}
}
Use AsyncTask, or (possibly) a separate thread.
http://developer.android.com/reference/android/os/AsyncTask.html
I would also throw in my 2 cents and say don't use TabActivity. Just have your own buttons that look like tabs, but that's not really critical to this topic.
I have a ListActivity which launches another Activity based on the list selection. This second Activity needs to load a fair bit of data from the internet and as such there is a noticeable delay between when the user clicks on an item and when the Activity displays.
This is a problem because I currently have no way to indicate to the user that their click is being processed (even just changing the colour of the selected list item would be sufficient but I can't find a good way to do that). Ideally I'd be able to display an indeterminate ProgressDialog while the second Activity is loading.
I've tried a few different approaches for this but nothing seems to work as desired.
I've tried the following:
Retrieving the serializable data (not all of it but some part) in an AsyncTask in the first Activity and passing it as an extra to the second. This didn't really work well as a ProgressDialog I created in onPreExecute() didn't display immediately (it seems delayed by the processing done in doInBackground() for some reason.)
Here is the code for that:
AsyncTask<String, Void, String> read = new AsyncTask<String, Void, String>() {
Dialog progress;
#Override
protected void onPreExecute() {
progress = ProgressDialog.show(SearchActivity.this,
"Loading data", "Please wait...");
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
DatasetReader reader = new DatasetReader();
reader.setFundID(params[0]);
reader.addDatsets(FundProfile.datasets);
reader.populate();
return reader.toString();
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progress.dismiss();
}
};
read.execute(selectedItem.getUniqueID());
try {
action = new Intent(SearchActivity.this, FundProfile.class);
action.putExtra("data", read.get());
} catch(Exception ex) {
ex.printStackTrace();
}
In the second Activity's onCreate() method (this does not work at all):
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarVisibility(true);
Here is the onCreate() method for the second approach:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setTitleColor(Color.WHITE);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarVisibility(true);
try {
setContentView(R.layout.fund_profile);
// init some data
setProgressBarVisibility(false);
} catch(Exception ex) {
FundProfile.this.finish();
}
}
If you have long operations you should not be doing them in onCreate in any case as this will freeze the UI (whether or not the activity is displayed). The UI set by onCreate will not appear and the UI will be unresponsive until after the onCreate call finishes.
It seems you can start your second activity and display a progress bar (or requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);), then start an ASyncTask which will be responsible for updating your UI once data has been retrieved.
Adam,
It sounds like you are looking for the Indeterminate Progress bar: http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/view/ProgressBar2.html
You can display this while you are loading your second Activity then set the visibility to false once the second Activity has loaded its data.
Move creating the Intent -- and really anything you need to do after the AsyncTask completes -- into onPostExecute:
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
progress.dismiss();
Intent action = new Intent(SearchActivity.this, FundProfile.class);
action.putExtra("data", result);
// ... do more here
}
The problem is that AsyncTask.get() blocks until the task is completed. So in the code above, the UI thread is blocked and the ProgressDialog is never given a chance to appear until the task completes.
I'm displaying some data by using SQLite. When I click on one button data come from database. It takes some time. At that time the screen is black. At that time I want to display the rotating spinner before the data dispay. Any ideas?
Android provides a ProgressDialog for accomplishing what you want.
First i would like to suggest to have a look at AsyncTask page, so that you will come to know about the AsyncTask exactly.
Now, Implement AsyncTask as given below:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new performBackgroundTask().execute();
}
private class performBackgroundTask extends AsyncTask <Void, Void, Void>
{
private ProgressDialog Dialog = new ProgressDialog(main.this);
protected void onPreExecute()
{
Dialog.setMessage(getString("Please wait..."));
Dialog.show();
}
protected void onPostExecute(Void unused)
{
Dialog.dismiss();
// displaying all the fetched data
}
#Override
protected Void doInBackground(Void... params)
{
// implement long-running task here i.e. select query/fetch data from table
// fetch data from SQLite table/database
return null;
}
}
Enjoy !!!
You should not execute long running tasks in UI thread as this blocks the UI redraw and makes app look unresponsive.
Use AsyncTask to execute long running tasks in background, while still updating the screen.
You can look at the standard music picker as one example of how to do this:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java
In addition to the whole "queries must be done off the main UI thread," this shows an indeterminant progress while first loading its data, fading to the list once the data is available. The function to start the query is here:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java#581
And to do the switch is here:
https://android.googlesource.com/platform/packages/apps/Music/+/master/src/com/android/music/MusicPicker.java#569
The layout has the list view put in a frame layout with another container holding the progress indicator and label. The visibility of these is changed to control whether the list or progress indicator are shown:
https://android.googlesource.com/platform/packages/apps/Music/+/master/res/layout/music_picker.xml