During android app onCreate I have a bunch of code that can be slow on some older devices. I want to have a progressdialog display while all the init code runs. Dialog won't show if called from onCreate because further code blocks the UI. So it needs to go into an AsyncTask.
This is my task.
class startupTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
pd = new ProgressDialog(mainContext);
pd.setMessage("Starting up. Please wait...");
pd.setIndeterminate(true);
pd.setCancelable(false);
pd.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
pd.show();
runInit();
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pd != null) {
pd.dismiss();
}
super.onPostExecute(result);
}
}
But the dialog still does not show? runInit is the usual slow startup code. It needs to run on the UI.
If I remove the pd.dismiss call the progress dialog does appear once the init codeis finished, so it is being created OK, just not displaying.
According to other posts the above code is the right way to do it, but when called from onCreate it does not seem to work?
Any ways to force a dialog to display after a call to show? Any way I can get the dialog to show and wait until it is visible before continuing?
Thanks for any help.
EDIT: In the end I just had to bite the bullet and reorganise code so that only the slow non UI code was inside the AsyncTask. This got it working.
What's your runInit is doing? You're running on the UI thread, it's being blocked the same way.
onPreExecute(), onPostExecute() and onProgressUpdate() have access to the UI Thread, but doInBackground() doesn't.
if runInit() does something on the UI it's being blocked and may be generating an exception that you're ignoring.
you should do operations on doInBackground and use publishProgress() to send to onProgressUpdate() data that you want to update to your UI / ProgressBar Status.
here's an example:
new AsyncTask<Void,Object,Void>()
{
#Override
protected Void doInBackground(Void... params)
{
Object[] _progress = new Object[]{"Decompressing", 1};
publishProgress(_progress);
}
#Override
protected void onPostExecute(Void params)
{
}
#Override
protected void onPreExecute()
{
}
#Override
protected void onProgressUpdate(Object... values)
{
txtProgress.setText(values[0].toString());
progressBar.setProgress(Integer.parseInt(values[1].toString()));
}
}.execute();
Related
So, my progress dialog not dismiss in onPostExecute. I'm using fragment. I didn't know where my problem is. I had search and try many solution, but all of that not working
As I said before, I had try many solution but it didn't work. And my progress dialog still show.
This is how I run the AsyncTask
new FetchDataServer().execute();
And here is my AsyncTask class code. Tell me where my mistake is.
private class FetchDataServer extends AsyncTask<String,String,String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
pd = true;
progressDialog.show(getActivity(), "Permintaan diproses", "Loading...");
}
#Override
protected String doInBackground(String... strings) {
getOneWayResult(input_data);
progressDialog.dismiss();
return null;
}
#Override
protected void onPostExecute(String s) {
Log.d("HAHA","Executed");
System.out.println("Masuk post execute");
if(progressDialog.isShowing() || pd){
progressDialog.dismiss();
pd = false;
}
}
}
I expected it to be dismiss immediately. It really disturbing my job. Currently in hurry to collect it. Thanks for your time.
I need to show simple progress bar dialog while some method not finish.
I Try to call it like
ProgressDialog progressDialog = ProgressDialog.show(Activity.this, "", "Please wait");
SyncCity()
SyncStreet()
progressDialog.dismiss();
But than app is blocked while method not finish,after that i get progress dialog,and in next second dissapear, sometimes i not See it at all.
All calling is going on button click...
Where is catch?
Thank You.
That's because you're blocking the UI thread. Try using AsyncTask, like this:
ProgressDialog progressDialog;
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
progressDialog = ProgressDialog.show(Activity.this, "", "Please wait");
}
#Override
protected Void doInBackground(Void... params) {
SyncCity()
SyncStreet()
return null;
}
#Override
protected void onPostExecute(Void args) {
progressDialog.dismiss();
}
}.execute();
You should use an AsyncTask to do such processes. You shouldn't do any process in the UI thread.
Here is a good example on how to use AsyncTask:
http://www.vogella.com/tutorials/AndroidBackgroundProcessing/article.html
I defined an AsyncTask in a button's onclicklistener, and once user clicks the button, ideally progress dialog shows while asynctask downloading.
However, progress dialog just flashes in and disappears before the results returned, and the button gets focused while the asynctask works in the background.
Can someone help me figure out what I did wrong here? Code snippet:
final ProgressDialog progressDialog = new ProgressDialog(context);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
((Button)findViewById(R.id.buttonLoginActivity)).setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
AsyncTask<Void, Void, Void> downloadTask= new AsyncTask<Void, Void, Void>(){
#Override
protected Void doInBackground(Void... params) {
String data = Service.getSomeData();
context.getContentResolver.notifyChange("content://some_url");
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(progressDialog== null) return;
if(progressDialog!=null) {
progressDialog.dismiss();
progressDialog = null;
}
}
};
progressDialog.show();
downloadTask.execute();
try{
downloadTask.get();
}catch(Exception e){
e.printStackTrace();
return;
}
}
});
Don't use get()
downloadTask.get();
this is a blocking call. From the Docs
Waits if necessary for the computation to complete, and then retrieves its result.
Just use execute() as you are then do what you need with the results in onPostExecute()
show the progressDialog on the onPreExecute which need to be writen, and it will run on the UI thread, not in background ( android 4 )
also I would call the async task on a new Handler().post(myAsynctaskcaller)
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog.show();
}
I am running an async task.
In the doinbackground method i have a method that returns int or some other value may be boolean value some times.
I also want to increase my progress bar as it goes to finishing.
problem is how to keep the track of counter ?
Some times db query may take some time and some times it goes faster . :)
public void getAllSchoolsSearchResult(InputBean nb , SearchLogic mLogic){
mSRLogic=mLogic;
new AsyncTask<Void, Integer, List<SResultModel>>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.setProgress(0);
mProgressDialog.setMax(100);
mProgressDialog.show();
}
#Override
protected List<SResultModel> doInBackground(
Void... paramArrayOfParams) {
progressbar_Status=0;
while(progressbar_Status<100){
progressbar_Status += 1;
publishProgress(progressbar_Status);
}
if(ConnectionProvider.checkConnection()==false){
return null;
}
return SearchResultHandler.searchStudent(searchAllSchools);
}
#Override
protected void onPostExecute(List<SResultModel> result) {
super.onPostExecute(result);
if(mProgressDialog!=null&&mProgressDialog.isShowing()){
mProgressDialog.dismiss();
}
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
mProgressDialog.setProgress(values[0]);
}
}.execute();
}
In the case of an unknown duration you should probably be using an indeterminate progress bar which you can set via the android:indeterminate layout property or setIndeterminate method.
If you know how many operations you're doing you can hold a member variable inside the asynctask or a local variable in the doInBackground method.
publishProgress can't be used like this.
From your code, you are showing the progress bar (while doing nothing) and then when it reaches 100% then you request the students.
The publishProgress should be inside the
SearchResultHandler.searchStudent()
depending on how it's implemented. If it doesn't have a loop inside, you won't be able to publish any progress.
In this cases, use an INDETERMINATE progress dialog, and do nothing in your doInBackground
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog.setIndeterminate(true);
mProgressDialog.show();
}
protected List<SResultModel> doInBackground(Void... paramArrayOfParams) {
if(!ConnectionProvider.checkConnection()) return null;
return SearchResultHandler.searchStudent(searchAllSchools);
}
I have a button on my app, if the user click it, it will refresh the current page by calling onResume(), and there are lots of database operations in onResume(). Instead of keeping the button stay pressed for a while, I would like to use asynctask to make a progressdialog while loading the data. But the problem is that the button will still be in pressed state and the progressdialog only show at the end of the operation for a very short duration.
RefreshButton.setOnClickListener(new OnClickListener()
{
public void onClick(View v)
{
onResume();
}
});
protected void onResume()
{
doneloading = false;
monResumeloading = new onResumeloading();
monResumeloading.execute();
....loading...
doneloading = true;
}
private class onResumeloading extends AsyncTask<Integer, Integer, String>
{
private ProgressDialog progressDialog;
#Override
protected void onPostExecute(String result)
{
progressDialog.dismiss();
}
#Override
protected void onPreExecute()
{
progressDialog = new ProgressDialog(StatisticsActivity.this);
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(true);
progressDialog.show();
Log.i(TAG, " doneloading=false");
}
#Override
protected void onProgressUpdate(Integer... values)
{
}
#Override
protected String doInBackground(Integer... params)
{
while(!doneloading)
{
publishProgress(0); //dummy
log.i(TAG, "loading");
}
return null;
}
}
I observed that the "loading" log is showing right after the asynctask execution and stop right after the boolean doneloading becomes false. But the progressdialog is not working properly. Please help me :(
First thing, I don't think you should be calling your AsyncTask in the onResume() function. You can simply call it from your ClickListener.
Right now, you are doing your '....loading...' code before you even execute your AsyncTask. That's why the button stays pressed while it's executing '....loading...' and then when it's done, it executes your AsyncTask which really isn't doing anything - that's why it just shows up for a short duration.
Move your '....loading...' code into your doInBackground() of your AsyncTask and it should work ok.
Summary:
Click: Execute AsyncTask
AsyncTask: opens ProgressDialog
AsyncTask: Executes your '...loading...' code
AsyncTask: Wait for '...loading...' code to complete while still displaying dialog.
AsyncTask: Dismiss ProgressDialog