I have an asynctask in which I pass an array of progressbars as a parameter. In the doinbackground method, I compute the progress of each progressbar and make a call to PublishProgress with progress as parameter. This is how I have done:
static volatile int currentProgressBarIndex;
#Override
protected Integer doInBackground(String... arg0) {
// TODO Auto-generated method stub
// display the images in now playing
while (ScheduleManager.isScheduleRunning) {
Iterator iterator = nowPlayingMediaSet.entrySet().iterator();
// set images on now playing
for (int i = 0; i < btnImgNowPlaying.length && iterator.hasNext(); ++i) {
Map.Entry mEntry = (Map.Entry) iterator.next();
Show mShowNowPlaying = (Show) mEntry.getKey();
// get show status
currentProgressBarIndex = i;
mProgressStatus[i] = ScheduleManager
.getCurrentPlayingShowStatus(mShowNowPlaying);
// Update the progress bar
publishProgress(mProgressStatus[i]);
}
// sleep 20 second to show the progress
try {
Thread.sleep(20000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Integer... progress) {
// TODO Auto-generated method stub
this.progBar[currentProgressBarIndex].setProgress(progress[0]);
}
What happens is that, only my last progressbar in the array is updated. Rest are updated, but later on.. I am sure I am doing something wrong here..
Related
I have read all solutions for the same question, but did not seem to find a answer.
I have a ProgressDialog which I am showing in the onPreExecute() of a AsyncTask. It does not dismiss after the doInBackground() is finished.
Here is my code:-
Main.java
case R.id.action_refresh:
new RefreshItems().execute();
return true;
private class RefreshItems extends AsyncTask<Void, Void, Void>
{
ProgressDialog refDialog ;
Fragment fragment = null;
List<News> updatedList;
#Override
protected void onPostExecute(Void result)
{
// TODO Auto-generated method stub
super.onPostExecute(result);
if(refDialog!=null && refDialog.isShowing() && refDialog.isIndeterminate())
refDialog.dismiss();
}
#Override
protected void onPreExecute()
{
// TODO Auto-generated method stub
super.onPreExecute();
refDialog = ProgressDialog.show(Home.this, "", "Please wait", true, false);
}
#Override
protected Void doInBackground(Void... params)
{
// TODO Auto-generated method stub
try
{
updatedList = new GetList().execute(items).get();
fragment = new HomeFragment(SPHostUrl,encodedAccountName,deviceAuthKey,usersname,avatarUrl, fullName,getApplicationContext(),updatedList);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
// TODO Auto-generated method stub
}
problem:
refDialog.isIndeterminate()
You are not measuring something so it will return false, so it is not dismissing your dialog.
solution:
remove it in your if statement
if(refDialog!=null && refDialog.isShowing())
Also remove this:
super.onPostExecute(result);
you dont need the default onPostExecute;
Edit:
problem 2:
ProgressDialog.show(Home.this, "", "Please wait", true, false);
you set the cancelable to false which mean you can not cancel it upon dismissing.
change your showing of dialog to this:
refDialog = ProgressDialog.show(Home.this, "", "Please wait")
Your below condition is becoming wrong in any manner,
if(refDialog!=null && refDialog.isShowing() && refDialog.isIndeterminate())
Just remove that condition and simply dismiss your dialog,
refDialog.dismiss();
Or,
Check your condition, that in which case its becoming wrong.
remove if(refDialog!=null && refDialog.isShowing()) from onPostExecute and it will work
if you really need to know if it is showing you can create a boolean visible=false; in the class set it true on preExecute ant check it on Post Exec
Make dialog field refDialog static and then try it
public static ProgressDialog refDialog ;
I am practicing the working of the AsyncTask and with that purpose I wanted to use the onProgressUpdate function. Currently in my program I have UI that lets the user choose an input (which would be show in a TextView after the AsyncTask is finished) and a timer (determines Thread.sleep() time in the AsyncTask)
What I want to do is ... if the user selects a time of 5. Then in every passing second I would like to send a notification to the UI (where a progress dialog is called) ... indicating progress of 1 of 5 ... 2 of 5 ... 3 of 5.
Here's the progress that I have made so far:
public class ViewFiller extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... input) {
// TODO Auto-generated method stub
try {
int time;
if (input[1].equalsIgnoreCase("")) {
time = 0;
} else {
time = Integer.parseInt(input[1]) * 1000;
for (int i = 1; i <= time / 1000; i++) {
publishProgress(i, time);
}
Thread.sleep(time);
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return input[0];
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
execute.setText("Execute");
progress.dismiss();
tvInput.setText(result);
}
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
execute.setText("Running...");
displayProgress("Updating field ... ");
// Start the progress dialog
progress.show();
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
progress.setMessage("Updating field ... " + values[0] + " of "
+ values[1] / 1000);
}
}
The current implementation only gives me 5 of 5 directly. Can anyone suggest me a solution ?
Because it is going through your loop faster than you see it
for (int i = 1; i <= time / 1000; i++) {
publishProgress(i, time);
You don't need the loop there. Just sleep for whatever amount of time then show your progress and have the sleep() and the publishProgress() in the loop. Something like
try {
int time = 0;
for (int i = 1; i <= time / 1000; i++) {
if (input[1].equalsIgnoreCase("")) {
time = 0;
} else {
time = Integer.parseInt(input[1]) * 1000;
publishProgress(time);
}
Thread.sleep(time);
}
Although, I'm not sure what input actually contains but you might want input[i]. It looks like its always going to be the same otherwise.
Also, CountDownTimer would be good for this I would think.
In the first run of my app, i have to copy database file to data folder. it takes about 10 sec and in this period of time user sees a black screen. I want to use AsynTask technique to show a progressbar. but it doesnt work an i see that progressbar after black screen goes away...
with this code i call copy database class and also i call AsynTsk process...
new asyn().execute();
try {
myDbHelper.createDataBase();
} catch (IOException ioe) {
// throw new Error("Unable to create database");
}
and this is my AsynTask code:
public class asyn extends AsyncTask<String, Integer, String> {
ProgressDialog dialog;
#Override
protected void onPreExecute()
{
//loading toast
//final DataBaseHelper myDbHelper = new DataBaseHelper(this);
String firstload2 = myDbHelper.getfirstload();
if(firstload2.matches("1")) {
dialog=new ProgressDialog(DictionaryActivity.this);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setMax(100);
dialog.show();
myDbHelper.changefirstload();
}
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
// perform desired task in this doInBackground Block.
for(int i=0;i<20;i++)
{
publishProgress(5);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return "";
}
#Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
dialog.incrementProgressBy(5);
}
#Override
protected void onPostExecute(String result)
{
dialog.dismiss();
AlertDialog.Builder a=new Builder(DictionaryActivity.this);
a.setMessage("Successfully Done");
a.setTitle("Try");
a.setPositiveButton("OK",null);
a.show();
}
}
where is my fault? how i can fix that?
myDbHelper.changefirstload(); should be within the doInBackground() method. onPreExecute() executes on the UI thread.
In terms of a progress bar, that's a bit difficult here. Personally, I'd do an indeterminate progress bar (just a spinning icon or something while it loads). If you want to have a % bar, though, you will need to break up the method into multiple methods, then update your progress in between them.
I want to add a simple process bar to my code with asy task. I tryed some exampels but cant see that process bar working.
I post here my code hope you can help me.
I want to stop process bar when some of my code is done like with some flag to stop the proses bar.
plese post some code.
thanks a lot!
here my code:
private class loading extends AsyncTask<Void, Void, Integer> {
Context context;
ProgressBar progressBar;
static final long waitTime = 1 * 4000L;
long preTime;
int progress;
public loading(Context context) {
this.context = context;
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
progressBar.setProgress(0);
}
protected void onPostExecute(Integer result) {
Intent intent = new Intent(this.context, first.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
finish();
return;
}
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
preTime = System.currentTimeMillis();
}
protected void onProgressUpdate(Integer... values) {
progressBar.setProgress(values[0]);
}
#Override
synchronized protected Integer doInBackground(Void... arg0) {
int waited = 0;
while (waited < 3000) {
try {
// SystemClock.sleep(100);
this.wait(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
waited += 100;
}
return null;
}
}
Your doInBackground method needs to call publishProgress() in order for you to update the UI.
After the line waited += 100; add:
int progress = Math.round((float)waited / 3000 * 100);
publishProgress(progress);
Also, the signature of AsyncTask is wrong if you intend on using an integer to reflect your progress. The generic parameters are AsyncTask<Params, Progress, Result>, so in your case, you're not accepting any arguments, or returning any meaningful value from doInBackground, but, you do want to return an Integer to indicate progress. So, change your class declaration to match:
private class loading extends AsyncTask<Void, Integer, Integer>
{
//your implementation
}
You are not calling AsyncTask.publishProgress and that is why your onProgressUpdate method is never called.
And by the way, your class name loading brokes naming conventions, that's not a good practice.
I'm using these codes to view an image from my application:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(imgFile), "image/*");
startActivity(intent);
I have no problem viewing the picture but when the size is a little bit larger, the intent keeps blank until the image is ready to load and show.
My question is, how can I show a ProgressBar, or in more advanced way, show a temporary image, before the real image get shown?
Thanks for the answer.
Try Asynctask as shown here:
try{
class test extends AsyncTask{
TextView tv_per;
int mprogress;
Dialog UpdateDialog = new Dialog(ClassContext);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
mprogress = 0;
UpdateDialog.setTitle(getResources().getString(R.string.app_name));
UpdateDialog.setContentView(R.layout.horizontalprogressdialog);
TextView dialog_message = (TextView)UpdateDialog.findViewById(R.id.titleTvLeft);
tv_per = (TextView)UpdateDialog.findViewById(R.id.hpd_tv_percentage);
dialog_message.setText(getResources().getString(R.string.dialog_retrieving_data));
dialog_message.setGravity(Gravity.RIGHT);
UpdateDialog.setCancelable(false);
UpdateDialog.show();
super.onPreExecute();
}
#Override
protected void onProgressUpdate(Object... values) {
// TODO Auto-generated method stub
ProgressBar update = (ProgressBar)UpdateDialog.findViewById(R.id.horizontalProgressBar);
update.setProgress((Integer) values[0]);
int percent = (Integer) values[0];
if(percent>=100)
{
percent=100;
}
tv_per = (TextView)UpdateDialog.findViewById(R.id.hpd_tv_percentage);
tv_per.setText(""+percent);
}
#Override
protected Object doInBackground(Object... params) {
// TODO Auto-generated method stub
//your code of UI operation
}
super.onPostExecute(result);
UpdateDialog.dismiss();
}
}
new test().execute(null);
}
catch(Exception e)
{
e.printStackTrace();
}
Also refer to this link: Fetch data from server and refresh UI when data is fetched?:)