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);
}
Related
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();
How can I edit the views of an activity from an AsyncTask BEFORE the task is complete? I cannot access any of the views from the doInBackground method, and I do not want to wait until the task has completed. Is there a way to go about doing this? Or do I have to create a thread within the doInBackground (which sounds to me would be bad practice) and then access the view on that thread's completion?
Override this method:
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
Call it in doInBackground() of your AsyncTask. This method publishProgress(Progress... values)
happens on the UI thread when you call it from doInBackground().
For more information, read AsyncTask
You could define the class MyAsyncTask containing the following:
private final ProgressDialog progressDialog;
public MyAsyncTask(Context context) {
super(context);
progressDialog = new ProgressDialog(context);
progressDialog.setTitle(R.string.title);
progressDialog.setButton(
DialogInterface.BUTTON_NEGATIVE,
context.getResources().getString(R.string.abort),
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
MyAsyncTask.this.cancel(true);
progressDialog.dismiss();
}
}
);
progressDialog.show();
}
#Override
protected void onProgressUpdate(String... params) {
progressDialog.setMessage(params[0]);
}
You can then use the ProgressDialog to report back to the GUI, e.g., by calling publishProgress("TEST").
You can update the UI from onProgressUpdate(). There is a tricky way, you can send some integer or boolean value to progress update and change your UI according to the condition.
#Override
protected void onProgressUpdate(Integer... values) {
if(values[0] == 1) {
// update the UI
button.settext("updating");
}
}
You can call onProgressUpdate fram asynctask by calling
publishProgress(1);
Hope this works, try out.
You need to override this method inside your AsynTask Class:
#Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
ProgressBar bar = (ProgressBar) findViewById(R.id.prgLoading);
bar.setIndeterminate(true);
super.onProgressUpdate(values);
}
You can define a progress bar as I show in here and set some value into it.
Error: Getting error with UI thread..
when I'm trying to show an alert inside the doInBackground. Is there any posibility do this stuff?
private class LoggingTask extends AsyncTask<String, Void, Integer> {
#Override
protected Integer doInBackground(String... params) {
//Get the sever connection and return the status
if(status==0){
// show an alert here....
}
return status;
}
#Override
protected Integer doInBackground(String... params) {
// Get the sever connection and return the status
publishProgress()
#Override
protected void onProgressUpdate(Void... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
//Do what ever you want
}
Do in background method doesnot allowed for UI changes,if you want to make any UI changes do in onpostexecute method
Do this way
#Override
protected Integer doInBackground(String... params) {
// Get the sever connection and return the status
if (status == 0) {
new Handler().post(new Runnable() {
#Override
public void run() {
// show an alert here....
}
});
}
return status;
}
Make a method that creates the dialog in your activty ( context would be the activity ) not in the AsyncTask. So when your
if ( status == 0 )
returns true, you call the method from the UI thread. In this way you are not creating the dialog in the AsyncTask and it should work.
doInBackground() is not the right place to do the UI related Task. You have to do it in onPostExecute. Or you can can start the dialog in OnPreExecute() and than cancel the dialog onPostExecute().
Async tasks don't run on the ui thread that's why you can't do that. Store a boolean. Then call the alert dialog after the asynchronous task completes in the onpostexecute method.
I use doInBackGround and AsyncTask method to show progress as below:
class UploadFile extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
showDialog(DIALOG_DOWNLOAD_PROGRESS);
}
#Override
protected String doInBackground(String... aurl) {
upload(ActionUrl, uploadFile, savepath, newName);
return null;
}
protected void onProgressUpdate(String... progress) {
mProgressDialog.setProgress(Integer.parseInt(progress[0]));
}
#Override
protected void onPostExecute(String unused) {
dismissDialog(DIALOG_DOWNLOAD_PROGRESS);
}
}
The upload(ActionUrl, uploadFile, savepath, newName); method is such as this.
And below code:
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_DOWNLOAD_PROGRESS: //we set this to 0
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Downloading file...");
mProgressDialog.setIndeterminate(false);
mProgressDialog.setMax(100);
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
mProgressDialog.setCancelable(true);
mProgressDialog.show();
return mProgressDialog;
default:
return null;
}
}
And below to call:
private ProgressDialog mProgressDialog;
public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
new UploadFile().execute("test");
But the Progress Dialog always show 0%, and never update.
How to modify to update it?
You have to call publishProgress(...) in your doInBackground(...) method. It's what causes onProgressUpdate(...) to be called. The onProgressUpdate(...) isn't called magically.
It's designed to be multi-purpose and it's your responsibility to trigger it through publishProgress(...) with whatever 'progress' data you want it to publish. It can be numeric such as 10 for 10 percent or a string such as First file downloaded....
The AsyncTask class has no idea what you want to publish or when - that's what a call to publishProgress(...) from doInBackground(...) is meant to do.
you will need to create the second thread which will track the progress and report it to this activity.Here is the link which has an example on how to accomplish this:
http://developer.android.com/guide/topics/ui/dialogs.html
In this link look for "Example ProgressDialog with a second thread"
I am working on an android app, in that app i have intent2 which on click redirects to intent3 and takes some time then loads a table and displays server data into it.
Sometimes if there is a lot of data, it tales pretty much time to get the dataload and the time blank screen is displayed increases.
i wish to show a loading bar till the data loads.
how can i show the ProgrssBar till only when data is not displayed ?
Probably your best bet would be to use AsyncTask in your "intent3":
You could do it like this:
private class performBackgroundTask extends AsyncTask <Void, Void, Void>
{
private ProgressDialog Dialog = new ProgressDialog(ClassName.this);
protected void onPreExecute()
{
Dialog.setMessage("Please wait...");
Dialog.show();
}
protected void onPostExecute(Void unused)
{
try
{
if(Dialog.isShowing())
{
Dialog.dismiss();
}
// do your Display and data setting operation here
}
catch(Exception e)
{
}
#Override
protected Void doInBackground(Void... params)
{
// Do your background data fetching here
return null;
}
}
You probably need to run an AsyncTask on onCreate when you open the new activity, the structure of the asynctask would be like this (taken from the google doc), notice that if you want to increament a progress bar you have to implement onProgressUpdate and call publishProgress in the doInBackground method
private class DownloadFilesTask extends AsyncTask<Void, Integer, Void> {
protected void onPreExecute()
{
// show your progress bar
}
protected Void doInBackground(Void... params) {
// do your work and publish the progress
publishProgress(progress);
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Void result) {
//dismiss your progress bar
}
}
This code is just an example, of course you need to adapt it to your logic/code.
Check out this simple and complete example