Showing a progressdialog in android while a large method is executed - java

I have a long running method that is called during onCreate, this method populates textviews so interacts with the UI, and updates maybe 70 labels (about 3-20 seconds depending on device).
I want to display a progressdialog as this method executes.
Ideally I want to fire my method on the UI thread once the Activity has been displayed and the progress is displayed, this I cannot do, the Activity won't paint until the method has finished.
I hoped to find an event which was fired after the activity was displayed, and I found the one below, but it still leaves the screen black until the method has finished.
#Override
public void onPostCreate(Bundle savedInstanceState)
I am normally a WP7 developer, and in .NET you add an event handler for onLoadComplete which is fired after the ui is displayed, but before the user has a chance to interact withthe UI, how do I do this in Android JAVA?
Thanks

Put a ProgressBar in the View.
Then in the onCreate() or onResume() method do this:
new Thread() {
public void run() {
yourLargeMethod();
}
}.start();
Now you can do this inside your method to update the progressBar
public void yourLargeMethod() {
// doSomething
...
runOnUiThread(new Runnable() {
public void run() {
// update the progress from the thread
progressBar.setProgress(x); // x is your progress, 0 <= x <= progressBar.getMax()
}
});
}

Related

Call a method when fragment is visible to user

I need execute a method when the fragment is visible (to the user).
Example:
I have 2 buttons (button 1 and button 2) ,
2 fragments(fragment 1 and fragment 2)
and the method loadImages() inside the class fragment 2.
when I press "button2" I want to replace fragment 1 by fragment 2
and then after the fragment 2 is visible (to the user) call loadImages().
I tried to use onResume() in the fragment class but it calls the method before the fragment is visible and it makes some delay to the transition.
I tried setUserVisibleHint() too and did not work.
A good example is the Instagram app. when you click on profile it loads the profile activity first and then import all the images.
I hope someone can help me. I will appreciate your help so much. Thank you.
Use the ViewTreeObserver callbacks:
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
final View view = v;
// Add a callback to be invoked when the view is drawn
view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
#Override
public void onDraw() {
// Immediately detach the listener so it only is called once
view.getViewTreeObserver().removeOnDrawListener(this);
// You're visible! Do your stuff.
loadImages();
}
});
}
I'm a little confused by what you are trying to do. It sounds like the images are loading too fast for you... so does that mean that you have the images ready to display? And that is a bad thing?
My guess (and this is just a guess) is that Instagram does not have the profile pictures in memory, so they have to make an API call to retrieve them, which is why they show up on a delay. If the same is the case for you, consider starting an AsyncTask in the onResume method of the fragment. Do whatever loading you need to do for the images in the background, and then make the images appear in the onPostExecute callback on the main thread. Make sure you only start the task if the images are not already loaded.
However, if you already have the images loaded in memory, and you just want a delay before they appear to the user, then you can do a postDelayed method on Handler. Something like this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadImages();
}
}, 1000);
Edit
As kcoppock points out, the handler code is pretty bad. I meant it to be a quick example, but it is so wrong I should not have included it in the first place. A more complete answer would be:
private Handler handler;
public void onResume(){
super.onResume();
if(handler == null){
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
loadImages();
}
}, 1000);
}
}
public void onDestroyView(){
super.onDestroyView();
handler.removeCallbacksAndMessages(null);
handler = null;
}
Use the onActivityCreated() callBck

Android Progress dialog does not dissmiss after method call

i am writing here to ask you a litlle question about the progress dialog.
In fact, i call web service in my application, the progress dialog works very well.
But when i change the date of my object to do the call of my web service,
the progress dialog appear, the results are receiveid. AND automatically, there is a new call of the web service and the progress dialog didn't dissmiss :-/
On my server JBoss, i can see the calls from my application.
At the first create of my activity i have one call.
But at the second call, when i changed the date, there are two call. i don't know why because when i change one of my spinner its works fine, the web service is call and returns the results.
I call the web service in a asynctask. I do nothing with the progress dialog in the asynctask.
Here is the method where i call the progress dialog
public void callWebService()
{
myProgressDialog = ProgressDialog.show(OverviewMoney.this,"", "Récupération liste des positions cash",true);
final Runnable runInUIThread = new Runnable() {
public void run() {
setListView();
}
};
new Thread() {
#Override public void run()
{
loadListMoney();
myProgressDialog.dismiss();
uiThreadCallback.post(runInUIThread);
myProgressDialog= null;
}
}.start();
}
The method loadListMoney call my web service in a asynctask and the method setListView put my resultList in an adapter to print the list on a list view.
Thanks in advance :-) (And sorry for my english)
Try this
public void callWebService()
{
if (myProgressDialog != null) myProgressDialog.dismiss();
myProgressDialog = ProgressDialog.show(OverviewMoney.this,"", "Récupération liste des positions cash",true);
final Runnable runInUIThread = new Runnable() {
public void run() {
setListView();
}
};
new Thread() {
#Override public void run()
{
loadListMoney();
myProgressDialog.dismiss();
uiThreadCallback.post(runInUIThread);
myProgressDialog= null;
}
}.start();
}
According to my understanding, when this function is called twice 1st time it will start progress dialog and quickly another function call is placed so without dismissing previous progress dialog you were creating one more progress dialog. So that was the main cause of it.

How can I show a Dialog box from a thread other than the UI thread

My app requires gps reading, so on the main thread I start a Thread that reads the GPS but I'm having trouble showing a dialog that says "Please wait". I tied also using a Handler, but that didn't work either. What's the best to control the "Please wait" dialog from the 2nd Thread? Thanks!
public void showWaitDialog() {
prgDialog = new ProgressDialog(context);
prgDialog.setTitle("Please wait.");
prgDialog.setMessage("Please wait.");
prgDialog.setCancelable(false);
prgDialog.show();
}
You can:
Define an Handler in your UI Thread (e.g. in the Activity) and then pass it to your thread. Now from the thread you call handler.post(runnable) to enqueue code to be executed on the UIThread.
Define a BroadcastReceiver in your Activity and from you thread send an Intent with the necessary information in the Bundle
Use an AsyncTask and the methods publishProgress(), onProgressUpdate() or onPostExecute() to inform the Activity of the progress or when the taask has finished
Use runOnUiThread.
It depends on your needs. For short-running asynchronous operations, AsyncTask is a good choice.
Why not use an AsyncTask. You can tell the Task on onPreExecute() to show the Please wait dialog, and then onPostExecute(Result result) you can remove the dialog. Those two methods are working on the UI thread while doInBackground(Params... params) is occurring in a background thread.
Example:
private class GetGPSTask extends AsyncTask<null, null, null>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
showWaitDialog(); <-Show your dialog
}
#Override
protected void doInBackground(null) {
//your code to get your GPS Data
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
HideDialogbox(); <-Code to hide the dialog box
}
}
Just remember to change the template types if you need to. Where it says AsynTask , the first value is passed to doInBackground, 2nd value is for progress value, 3rd value is a return value from doInBackground to onPostExecute.
As other answers have rightly suggested, you can preferably use AsyncTask. Here is an exampleof how to use it for your purpose: AsyncTask Android example. Otherwise you may use runOnUiThread method as well. From inside your second thread to make the changes on UI thread ( eg: Dialogs and Toasts). According to its documentation, it says:
It runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
For eg;
Your_Activity_Name.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
showWaitDialog();
}
});
See display progressdialog in non-activity class and Loading Dialog with runOnUiThread for update view on Android.
hope this helps.

add progress spinner to app boolean

In my code i have a boolean to install information to the database via preference. It works fine but the issue is now that have alot of information to add to the app and i get a black screen while the information is being added to the sqlite (only during installation). How can i add a progress spinner so the users will know the app is in the installation process. I am afraid they will think the app is broken when they stare at the black screen.
/** Insert list into db once */
if (pref.getBoolean("isFirst", true)) {
readBLContactsfromAssetsXMLToDB("list.xml");
pref.edit().putBoolean("isFirst", false).commit();
}
addQuickActions();
}
First you may use AsyncTask for doing processes that take long time. If you are not aware of it, it allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
But if you insist not to use that, then since you are blocking the UI thread, you cannot show the dialog and do your stuff at the same time. You need to have a background thread for the lengthy process, and show the progress dialog on the UI thread.
There are lots of examples of AsyncTaks online. Just for sample:
private class OuterClass extend Activity{
//....
#Override
public void onCreate(Bundle savedInstanceState) {
new performBackgroundTask ().execute();
}
//....
private class performBackgroundTask extends AsyncTask < Void, Void, Void >
{
private ProgressDialog dia;
// This method runs in UI thread before the background process starts.
#Override
protected void onPreExecute(){
// Show dialog
dia = new ProgressDialog(OuterClass.this);
dia.setMessage("Installing...");
dia.show();
}
#Override
protected Void doInBackground(Void... params) {
// Do all the stuff here ...
addQuickActions();
}
// Ececutes in UI thread after the long background process has finished
#Override
protected void onPostExecute(Void result){
// Dismiss dialog
dia.dismiss();
}
}
}
You may see How to display progress dialog before starting an activity in Android?
Hope this helps.

Android execute when multiple tasks are done

I'm working on an app that downloads information from my server after an NFC card has been detected.
When a card is detected, I start
- an Asynctask to download some data from my server
- an animation of a popup appearing on the screen
After both the asynctask and the animation are done, I want to start a method that displays the downloaded data in the popup.
What is the correct way to trigger this new method? It can only start when both conditions are met.
In the async task you use to download data add the onPostExecute method to remove the animation popup and show the downloaded data as well like this :
protected void onPostExecute(Long result) {
//put code to disable animation popup
//code for displaying downloaded data popup
}
For more info check out http://developer.android.com/reference/android/os/AsyncTask.html
you Animation object has the method setAnimationLister. It takes as parameter a Class Object that implements the interface Animation.AnimationListener . This interface requires three methods to be implemented:
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
The onAnimationEnd is triggered when the animation ends. If I have not misunderstood you, this is what you need
EDIT:
you could have two booleans value, boolean animationFinished = false, downloadFinished = false; When onPostExecute is called put downloadFinished to true and call yourMethod.
When onAnimationEnd is triggered animationFinished = true and call yourMethod. yourMethod should start like:
if (!animationFinished || !downloadFinished)
return;

Categories

Resources