Best way to manage the ProgressDialog from AsyncTask
I would rather isolate business logic stuff from AsyncTask than isolate AsyncTask from Activity.
In general, AsyncTask has a very specific design and use case in Android application life cycle, that is, run some time consuming task in the background thread, once done, update Activity's view in UI thread. This is why it is always recommended to use it as a inner class of Activity.
A more OO design IMO is isolating and centralizing your business logic into a POJO (for reusability). For testability, you can do something like this:
1. Define an interface IBusinessDAO
2. Define RealBusinessDAO implements IBusinessDAO
3. Define MockBusinessDAO implements IBusinessDAO
4. Call IBusinessDAO.foo(); inside AsyncTask.doInBackground()
For unit-test your business logic, as it is a POJO, you can use purely JUnit write your test case. Sometimes we want to test UI component and we don't really care how underlying business logic is implemented, for instance, my business logic connect to remote http server download some json data, I don't want to do this every time when I just want to test the UI layout, for this situation, I can easily change my Activity use MockBusinessDAO (sort of Spring's DI concept) like this:
public class MyActivity extends Activity {
IBusinessDAO businessDAO;
... ...
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
... ...
protected void doInBackground(Void... params) {
businessDAO.foo();
}
}
... ...
public void onCreate(Bundle savedInstanceState) {
if (runInTest)
businessDAO = new MockBusinessDAO();
else
businessDAO = new RealBusinessDAO();
new myAsyncTask().execute();
}
}
Some advantages of doing these are:
1. AsyncTask implementation is easy and clean (several lines of code in doInBacnground())
2. Business logic implementation is purely POJO, improve reusability.
3. Isolation test business logic and UI component, improve testability.
Hope that help.
ProgressDialog in AsyncTask
Fixed by moving the view modifiers to onPostExecute so the fixed code is :
public class Soirees extends ListActivity {
private List<Message> messages;
private TextView tvSorties;
//private MyProgressDialog dialog;
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.sorties);
tvSorties=(TextView)findViewById(R.id.TVTitle);
tvSorties.setText("Programme des soirées");
new ProgressTask(Soirees.this).execute();
}
private class ProgressTask extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog;
List<Message> titles;
private ListActivity activity;
//private List<Message> messages;
public ProgressTask(ListActivity activity) {
this.activity = activity;
context = activity;
dialog = new ProgressDialog(context);
}
/** progress dialog to show user that the backup is processing. */
/** application context. */
private Context context;
protected void onPreExecute() {
this.dialog.setMessage("Progress start");
this.dialog.show();
}
@Override
protected void onPostExecute(final Boolean success) {
List<Message> titles = new ArrayList<Message>(messages.size());
for (Message msg : messages){
titles.add(msg);
}
MessageListAdapter adapter = new MessageListAdapter(activity, titles);
activity.setListAdapter(adapter);
adapter.notifyDataSetChanged();
if (dialog.isShowing()) {
dialog.dismiss();
}
if (success) {
Toast.makeText(context, "OK", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(context, "Error", Toast.LENGTH_LONG).show();
}
}
protected Boolean doInBackground(final String... args) {
try{
BaseFeedParser parser = new BaseFeedParser();
messages = parser.parse();
return true;
} catch (Exception e){
Log.e("tag", "error", e);
return false;
}
}
}
}
@Vladimir, thx your code was very helpful.
How to set progress dialog in AsyncTask
You should Override onPreExecute() method before doInBackground method.
ProgressDialog myPd_bar;
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
myPd_bar=new ProgressDialog(AndroidGridLayoutActivity.this);
myPd_bar.setMessage("Loading....");
myPd_bar.setTitle(title);
myPd_bar.show();
super.onPreExecute();
}
Then you should Override onPostExecute() method after doInBackground method.
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
myPd_bar.dismiss();
}
You can find more information from this link
Android ProgressDialog in AsyncTask
You are trying to do a parseInt
on a String containing "Loaded "+progress+"%"
. It can't work. Try this :
publishProgress(""+progress);
// [...]
protected void onProgressUpdate(String... progress)
{
Log.d("ANDRO_ASYNC", "Loaded " + progress[0] + "%");
pd.setProgress(Integer.parseInt(progress[0]));
}
How to use progress dialog in AsyncTask in android
no need to return current Activity instance from doInBackground
because AsyncTask
is inner class of Activity so you just use LoginActivity.this
to start next Activity change your AsyncTask class as :
private class log_in extends AsyncTask<String,Void,String>{
ProgressDialog pDialog;
@Override
protected void onPreExecute(){
pDialog = new ProgressDialog(LoginActivity.this);
pDialog.setMessage("Authenticating user...");
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
login();
return null;
}
protected void onPostExecute(String params){
super.onPostExecute(params);
pDialog.dismiss();
if(userverified==true){
Intent intent=new Intent(LoginActivity.this,menu.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
LoginActivity.this.startActivity(intent);
}
else{
error.setText("Wrong password or username combination");
}
}
}
because it's not possible to updating UI elements from doInBackground
and you are trying to set textview text inside login()
method instead of changing Textview text just make userverified==false
android how to work with asynctasks progressdialog
onProgressUpdate()
is used to operate progress of asynchronous operations via this method. Note the param with datatype Integer
. This corresponds to the second parameter in the class definition. This callback can be triggered from within the body of the doInBackground()
method by calling publishProgress()
.
Example
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class AsyncTaskExample extends Activity {
protected TextView _percentField;
protected Button _cancelButton;
protected InitTask _initTask;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
_percentField = (TextView) findViewById(R.id.percent_field);
_cancelButton = (Button) findViewById(R.id.cancel_button);
_cancelButton.setOnClickListener(new CancelButtonListener());
_initTask = new InitTask();
_initTask.execute(this);
}
protected class CancelButtonListener implements View.OnClickListener {
public void onClick(View v) {
_initTask.cancel(true);
}
}
/**
* sub-class of AsyncTask
*/
protected class InitTask extends AsyncTask<Context, Integer, String> {
// -- run intensive processes here
// -- notice that the datatype of the first param in the class definition matches the param passed to this
// method
// -- and that the datatype of the last param in the class definition matches the return type of this method
@Override
protected String doInBackground(Context... params) {
// -- on every iteration
// -- runs a while loop that causes the thread to sleep for 50 milliseconds
// -- publishes the progress - calls the onProgressUpdate handler defined below
// -- and increments the counter variable i by one
int i = 0;
while (i <= 50) {
try {
Thread.sleep(50);
publishProgress(i);
i++;
}
catch (Exception e) {
Log.i("makemachine", e.getMessage());
}
}
return "COMPLETE!";
}
// -- gets called just before thread begins
@Override
protected void onPreExecute() {
Log.i("makemachine", "onPreExecute()");
super.onPreExecute();
}
// -- called from the publish progress
// -- notice that the datatype of the second param gets passed to this method
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.i("makemachine", "onProgressUpdate(): " + String.valueOf(values[0]));
_percentField.setText((values[0] * 2) + "%");
_percentField.setTextSize(values[0]);
}
// -- called if the cancel button is pressed
@Override
protected void onCancelled() {
super.onCancelled();
Log.i("makemachine", "onCancelled()");
_percentField.setText("Cancelled!");
_percentField.setTextColor(0xFFFF0000);
}
// -- called as soon as doInBackground method completes
// -- notice that the third param gets passed to this method
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i("makemachine", "onPostExecute(): " + result);
_percentField.setText(result);
_percentField.setTextColor(0xFF69adea);
_cancelButton.setVisibility(View.INVISIBLE);
}
}
}
How to use AsyncTask to show a ProgressDialog while doing background work in Android?
Place your ProgressDialog
in onPreExecute
, sample code below:
private ProgressDialog pdia;
@Override
protected void onPreExecute(){
super.onPreExecute();
pdia = new ProgressDialog(yourContext);
pdia.setMessage("Loading...");
pdia.show();
}
@Override
protected void onPostExecute(String result){
super.onPostExecute(result);
pdia.dismiss();
}
and in your onClickListener
, just put this line inside:
new EfetuaLogin().execute(null, null , null);
Cancel AsyncTask with Progress Dialog button
@Override
protected void onPreExecute() {
pDialog = new ProgressDialog(DSDactivity.this);
pDialog.setMessage(getResources().getString(R.string.pDialog));
pDialog.setCancelable(true);
pDialog.setButton(DialogInterface.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
myTask.cancel(true);
dialog.dismiss();
}
}
}
And then, as my link said, create your AsyncTask and store it :
MyAsyncTask myTask=null;
and execute it like this :
myTask = new MyAsyncTask();
myTask.execute();
How to run ProgressDialog in AsyncTask
The progress dialog require to pass the context of your activity. As you suppose to are trying.
progress = new ProgressDialog(context);
Now question is how to pass the context to the progress dialog. Simply the calling of this class. class syncX extends AsyncTask<String, String, String>{}
should pass the context to the progress dialog. See the below modify version class.
class syncX extends AsyncTask<String, String, String>
{
ProgressDialog progress;
Context mContext;
public syncX(Context context){
this.mContext= context;
}
public Context getContext(){
return mContext;
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
progress = new ProgressDialog(getContext());
progress.setMessage("Setting BigBoard ");
progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progress.setIndeterminate(true);
progress.show();
}
@Override
protected String doInBackground(String... params)
{
return null;
}
@Override
protected void onPostExecute(String file_url)
{
}
}
Inside your BigBoard class it should look like.
new syncX(this).execute();
Done Cheers!
Related Topics
Change Package Name for Android in React Native
Android: How to Draw a Border to a Linearlayout
How to Get Charles Proxy Work with Android 7 Nougat
Android: How to Programmatically Set the Size of a Layout
Trying to Add Adb to Path Variable Osx
Missing Contentdescription Attribute on Image' in Xml
Runonuithread VS Looper.Getmainlooper().Post in Android
How to Add -Xlint:Unchecked to My Android Gradle Based Project
Glide Image Loading with Application Context
Put Buttons at Bottom of Screen with Linearlayout
Packaging Android Resource Files Within a Distributable Jar File
Making a Database Backup to Sdcard on Android
Android Xml Layout Parameters Do Not Function as Expected
Understanding Canvas and Surface Concepts
How to Set Google Map Fragment Inside Scroll View