Java AsyncTask not showing progress on UI though publishProgress(progress) - java

In my android app, i am doing time consuming task extending AsyncTask, and want to display the progress in Toast messages. Toast messages are also displayed onPre() and onPost().
I am able to display Toast messages onPre() & onPost() but not able to show onProgressUpdate(Integer... progress).
Following is my code...
public class MainClass extends Activity {
public void Start(View view) {
DemoTasks runner = new DemoTasks(this);
runner.execute("Start");
}
private class DemoTasks extends AsyncTask<String, Integer, Integer> {
private Context context;
public DemoTasks(Context context){
this.context = context;
}
#Override
protected Integer doInBackground(String... params) {
try {
publishProgress(0);
doWork();
Thread.sleep(5000L);
publishProgress(100);
} catch (Exception localException) {
Log.d("POST", localException.getMessage());
}
return 100;
}
#Override
protected void onPostExecute(Integer result) {
Toast.makeText(context, "post", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPreExecute() {
Toast.makeText(context, "pre", Toast.LENGTH_SHORT).show();
}
#Override
protected void onProgressUpdate(Integer... progress) {
super.onProgressUpdate(progress);
Toast.makeText(context, "progress-" + progress, Toast.LENGTH_SHORT).show();
}
}
}
Also in my doInBackgroud(String...params) ...Thread.sleep is also not working.
As soon as onPre() gets executed, onPost() also executes after that!!!!

You can try this,
showProgress ();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
dialog.cancel();
Intent i=new Intent(getApplicationContext(),Main.class);
startActivity(i);
finish();
}
}, 3000); //number of seconds
private ProgressDialog dialog;
public void showProgress () {
dialog = new ProgressDialog(this);
dialog.setCancelable(true);
dialog.setMessage("Please wait");
dialog.show();}
Bascially,you can access the UI on any method, even In doinBackground you can access the UI using runOnUIthread.

here is one AsyncTask Example. This will show a peogress dialog while executing the task.
private class LoginProcessing extends AsyncTask<Object, Void, Void> {
private LoginCredentials myLoginCredentials;
private ProgressDialog progressDialog;
public LoginProcessing(LoginCredentials Credentials) {
super();
myLoginCredentials=Credentials;
progressDialog.setMax(100);
progressDialog.setMessage("Please Wait..");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setProgress(0);
progressDialog.show();
}
protected void onPreExecute (){
}
#Override
protected Void doInBackground(Object... arg0) {
// TODO Auto-generated method stub
//Code to do the process in background
return null;
}
#Override
protected void onProgressUpdate(Long... progress) {
// int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5);
progressDialog.setProgress(progress);
}
protected void onPostExecute(Void result){
progressDialog.dismiss();
//Your code after the process
}
}
You can call this Task as,
new LoginProcessing(loginCredentials).execute();
In this Example loginCredentials is the parameter I am passing to the AsyncTask. You can change it to your own parameter.

Related

Android dialog dismiss after certain computation

I'm encountering the following problem:
I created a waiting spinner using Dialog like this
final Dialog progDialog = new Dialog(context);
progDialog.setContentView(R.layout.progress_dialog);
progDialog.setTitle("Calculating...");
progDialog.setCancelable(false);
progDialog.setCanceledOnTouchOutside(false);
WindowManager.LayoutParams lp = progDialog.getWindow().getAttributes();
lp.dimAmount = 0.7f;
progDialog.show();
Afterwards, I'm calculating something in the background
for()...
for()...
After the calculation is finished, I want to dismiss my dialog with
progDialog.dismiss();
However, this results in my dialog never being shown at all. When I remove the last line, the dialog is shown but is never dismissed. Is there a fix to it?
You better try with AsyncTask
private class YourAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog progDialog;
public YourAsyncTask(MyMainActivity activity) {
progDialog = new ProgressDialog(activity);
}
#Override
protected void onPreExecute() {
progDialog.setContentView(R.layout.progress_dialog);
progDialog.setTitle("Calculating...");
progDialog.setCancelable(false);
progDialog.setCanceledOnTouchOutside(false);
progDialog.show();
}
#Override
protected Void doInBackground(Void... args) {
// do background work here
return null;
}
#Override
protected void onPostExecute(Void result) {
// do UI work here
if (progDialog.isShowing()) {
progDialog.dismiss();
}
}
}
Use the above code in your Main Activity. And, do your calculation part in doInBackground.
To set timer for your computation try below code:
Runnable progressRunnable = new Runnable() {
#Override
public void run() {
progDialog.cancel();
}
};
Handler pdCanceller = new Handler();
pdCanceller.postDelayed(progressRunnable, 3000);
Adding show/hide:
progDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
theLayout.setVisibility(View.GONE);
}
});
Update:
ProgressDialog class was deprecated as of API 26

Issues about thread stopped or not in progressDialog in Android with AsyncTask

I have a code as following, and the thing is every time I cancel the dialog, InterruptException occurs and the cancel method doesn't really work. As I shows below, I print the state of cancel in the onPostExecute method, it is a false instead of true. Before adding isRunning parameter, obviously the thread was still running in the background. Although isRunning does stop the thread( the onPostExecute method was executed), I want to know why the exception happened and why I still got a false in the isCanceled method. Thanks!
public void startDownload(View view){
dialog = new ProgressDialog(this);
final Downloader downloader = new Downloader(this, dialog);
downloader.execute(0);
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
downloader.cancel(true);
}
});
}
public class Downloader extends AsyncTask<Integer, Integer, String> {
private Context context;
private PowerManager.WakeLock wakeLock;
private ProgressDialog dialog;
public boolean isRunning = true;
public Downloader(Context context, ProgressDialog dialog) {
this.context = context;
this.dialog = dialog;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
getClass().getName());
wakeLock.acquire();
dialog.setMessage("Downloading...");
dialog.setIndeterminate(true);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.setCancelable(false);
dialog.setButton(ProgressDialog.BUTTON_NEGATIVE, "Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
isRunning = false;
}
});
dialog.show();
}
#Override
protected String doInBackground(Integer[] params) {
int count = params[0];
while(count<100 && isRunning){
publishProgress(count);
try{
count++;
System.out.println(count);
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
dialog.setIndeterminate(false);
dialog.setMax(100);
dialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
wakeLock.release();
dialog.dismiss();
if (s != null)
Toast.makeText(context,"Download error: "+ s, Toast.LENGTH_LONG).show();
else
Toast.makeText(context,"File downloaded", Toast.LENGTH_SHORT).show();
System.out.println(isCancelled());
}
}
Make sure you're not executing another AsyncTask, or start this one in parallel, using .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) instead of .execute(). Otherwise, if you're already running another AsyncTask in background this other one will not run until that last one finishes.
On the other hand, try not to track AsyncTask lifecycle status with a custom boolean, to do so, use isCancelled() to check stuff at runtime or break any loop and if required, override the AsyncTask's onCancelled() method to implement any functionality you may need at that point.
Don't forget to check the reference: AsyncTask - Android Developers.

Android Splash Screen AsyncTask

Basically I have a loading splash screen which will be executed when button was clicked:
public void onClick(View v) {
// Load the loading splash screen
Intent loadingIntent = new Intent(context, LoadingScreen.class);
context.startActivity(loadingIntent);
}
});
And in the LoadingScreen class:
public class LoadingScreen extends Activity{
//A ProgressDialog object
private ProgressDialog progressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Initialize a LoadViewTask object and call the execute() method
new LoadViewTask().execute();
}
//To use the AsyncTask, it must be subclassed
private class LoadViewTask extends AsyncTask<Void, Integer, Void>
{
//Before running code in separate thread
#Override
protected void onPreExecute()
{
progressDialog = ProgressDialog.show(LoadingScreen.this,"Getting routes...",
"Loading data, please wait...", false, false);
}
//The code to be executed in a background thread.
#Override
protected Void doInBackground(Void... params)
{
try
{
//Get the current thread's token
synchronized (this)
{
//Initialize an integer (that will act as a counter) to zero
int counter = 0;
//While the counter is smaller than four
while(counter <= 4)
{
//Wait 850 milliseconds
this.wait(750);
//Increment the counter
counter++;
//Set the current progress.
//This value is going to be passed to the onProgressUpdate() method.
publishProgress(counter*25);
}
}
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return null;
}
//Update the progress
#Override
protected void onProgressUpdate(Integer... values)
{
//set the current progress of the progress dialog
progressDialog.setProgress(values[0]);
}
//after executing the code in the thread
#Override
protected void onPostExecute(Void result)
{
finish();
//close the progress dialog
progressDialog.dismiss();
}
}
}
With these codes, the loading splash screen did came out. But I wonder is there any other way to show only the pop out dialogue for loading progress bar which on top on my previous screen?
Let's say my previous screen was event details. Then when user selected the button, only the dialogue box with loading progress bar will be shown instead of a new intent with a dialogue box.
Any ideas? Thanks in advance.
EDIT
public void onClick(View v) {
// Load the loading splash screen
new LoadViewTask().execute();
ENeighbourhoodActivity.tvDirection.setText("");
eventModel.setEventX(String.valueOf(eventModel.getEventX()));
eventModel.setEventY(String.valueOf(eventModel.getEventY()));
new GetEventDirectionAsyncTask(new GetEventDirectionAsyncTask.OnRoutineFinished() {
public void onFinish() {
//Hide the callout and plot user location marker
ENeighbourhoodActivity.callout.hide();
EventController.getUserLocation(context);
getActivity().finish();
}
}).execute(eventModel);
}
});
public class GetRegisteredEventAsyncTask extends
AsyncTask<String, Integer, Double> {
static EventController eventCtrl = new EventController();
public static ArrayList<Event> upcomingModel = new ArrayList<Event>();
public static ArrayList<Event> pastModel = new ArrayList<Event>();
public interface OnRoutineFinished { // interface
void onFinish();
}
private OnRoutineFinished mCallbacks;
public GetRegisteredEventAsyncTask(OnRoutineFinished callback) {
mCallbacks = callback;
}
public GetRegisteredEventAsyncTask() {
} // empty constructor to maintain compatibility
#Override
protected Double doInBackground(String... params) {
try {
upcomingModel = eventCtrl.getRegisteredUpcomingEvent(params[0]);
pastModel = eventCtrl.getRegisteredPastEvent(params[0]);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(Double result) {
if (mCallbacks != null)
mCallbacks.onFinish(); // call interface on finish
}
protected void onProgressUpdate(Integer... progress) {
}
}
In your onClick() method you could write something like:
new LoadViewTask().execute();
and the progress dialog will be shown in that page itself.
what are you doing man, just call your AsyncTask not the intent
public void onClick(View v)
{
new LoadViewTask().execute();
}
});
do your intent in postExecute
#Override
protected void onPostExecute(Void result)
{
finish();
//close the progress dialog
progressDialog.dismiss();
//START YOUR ACTIVITY HERE
Intent loadingIntent = new Intent(context, LoadingScreen.class);
context.startActivity(loadingIntent);
}
Must read the documentation of AsynTask

ProgressBar not showing up during a AsyncTask

I am trying to make a simple task in background and show a progress bar while it is being done.
This is the code for the main (and the only) Activity:
public class Login extends Activity {
public static ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
(...)
this.getWindow().requestFeature(Window.FEATURE_PROGRESS);
this.getWindow().setFeatureInt(Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
progressDialog = new ProgressDialog(activity);
progressDialog.setMessage("Sending data...");
progressDialog.setCancelable(false);
(...)
// In some onClick Eevent..
JSONObject result = new Urltasks().execute(...).get();
(...)
}
}
This is the code for the activity:
class Urltasks extends AsyncTask<String, Integer, JSONObject>{
protected void onPreExecute() {
System.out.println("Inicia onPreExecute");
Login.progressDialog.show();
}
protected void onPostExecute(String result) {
Login.progressDialog.dismiss();
}
protected JSONObject doInBackground(String... arg0) {
// Some work being done. I do not use Login.progressDialog here
}
}
With this code the ProgressDialog shows up when the task ends, and it doesn't dismiss.
Problem is here:
JSONObject result = new Urltasks().execute(...).get();
Calling get() on an AsyncTask blocks the current thread, i.e. your UI thread, until the AsyncTask is executed. Therefore the progress dialog cannot run. Remove the get().
To obtain the result of the AsyncTask, you can e.g. pass in a listener callback to the asynctask that gets notified when the result is available:
class YourAsyncTask extends AsyncTask<ParamType, ProgressType, ResultType> {
private YourResultListener mListener;
interface YourResultListener {
void onResultAvailable(ResultType result);
}
YourAsyncTask(YourResultListener listener) {
mListener = listener;
}
#Override protected ResultType doInBackground(ParamType... params) {
//...
}
#Override protected void onPostExecute(ResultType result) {
mListener.onResultAvailable(result);
}
}
You can use it like:
mProgressDialog.show();
new YourAsyncTask(new YourResultListener() {
#Override void onResultAvailable(ResultType result) {
mProgressDialog.dismiss();
// use result
}).execute(params);
Personally I like to keep user interface elements such as progress dialogs decoupled from async tasks.
Don't put your progress dialog in your log in class. Keep it in the async task
this is how you show your dialog
progressDialog = ProgressDialog.show(yourActivityHERE.this, "",
"Loading... please wait.");
Edited this for you:
class Urls extends AsyncTask<String, Integer, JSONObject>{
ProgressDialog progressDialog;
protected void onPreExecute() {
progressDialog = ProgressDialog.show(yourActivityHERE.this, "",
"Loading... please wait.");
}
protected void onPostExecute(String result) {
progressDialog.dismiss();
}
protected JSONObject doInBackground(String... arg0) {
// Some work being done. I do not use Login.progressDialog here
}
}
create the constructor in your Urltasks sending the context of the calling class.
then use that context to create the progress dialog in the preExecute of your Urltasks
class Urltasks extends AsyncTask<String, Integer, JSONObject>{
Context mContext;
public static ProgressDialog progressDialog;
public UrlTasks(Context c){
mContext=c;
}
protected void onPreExecute() {
progressDialog = new ProgressDialog(mContext);
progressDialog.setMessage("Sending data...");
progressDialog.setCancelable(false);
progressDialog.show();
}
protected void onPostExecute(String result) {
progressDialog.dismiss();
}
protected JSONObject doInBackground(String... arg0) {
// Do your work here
}
}

How to show "Loading" status in Android?

I'm making an Android application and it has to load some data though Internet (only some data-- not all). So when the data is loading, and the Internet connection is slow, I want to show a "Loading..." icon to the user.
So how can I do this? Show a "Loading..." icon while the data is being loaded in the background, and when its completely loaded, hide the icon?
Thanks in advance!
use Async Task for your status.
new SomeTask(0).execute();
/** Inner class for implementing progress bar before fetching data **/
private class SomeTask extends AsyncTask<Void, Void, Integer>
{
private ProgressDialog Dialog = new ProgressDialog(yourActivityClass.this);
#Override
protected void onPreExecute()
{
Dialog.setMessage("Doing something...");
Dialog.show();
}
#Override
protected Integer doInBackground(Void... params)
{
//Task for doing something
return 0;
}
#Override
protected void onPostExecute(Integer result)
{
if(result==0)
{
//do some thing
}
// after completed finished the progressbar
Dialog.dismiss();
}
}
Use AsyncTask along with progress dialog on task completion..That will do..
Use asynctask for Background operations, then display progress dialog like below
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;
}
}
}
}
In the onCreate method:
WebView mWebView;
ProgressDialog pgDiagWebView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webview);
pgDiagWebView = ProgressDialog.show(CreateAccountWebView.this, "Loading", "Wait", true);
mWebView = (WebView) findViewById(R.id.registerWebView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebViewClient(new ResgisterWebViewClient());
mWebView.loadUrl("http://www.google.com/");
}
class ResgisterWebViewClient extends WebViewClient {
#Override
public void onPageFinished(WebView view, String url) {
// TODO Auto-generated method stub
super.onPageFinished(view, url);
pgDiagWebView.dismiss();
}
}

Categories

Resources