i have an issue with an AsyncTask. I have an Activity with three CheckBox that if checked launch the async task when the user press the button. My async is this
private class MyTask extends AsyncTask<Void, Void, Void> {
String valore
public MyTask(String valore) {
this.valore = valore;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage(getString(R.string.message));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
// Exec some operations
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
if(risultato != null) {
textView.append(risultato);
}
if(errori != null) {
textView.append(errori);
}
progressDialog.dismiss();
}
}
And the button
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(checkBox.isChecked()) {
new MyTask("string").execute();
}
if(checkBox2.isChecked()) {
new MyTask("string2").execute();
}
if(checkBox3.isChecked()) {
new MyTask("string3").execute();
}
}
});
The problem is that if two or three checkbox are checked the ProgressDialog is not dismissed and remain on the screen. Why? How can i dismiss it also when two or more checkbox are checked?
try {
if ((pDialog != null) && pDialog.isShowing()) {
pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
pDialog = null;
}
Try dismissing the dialog like this It might solve your problem
There are problem in this code
public void onClick(View v) {
// TODO Auto-generated method stub
if(checkBox.isChecked()) {
new MyTask("string").execute();
}
if(checkBox2.isChecked()) {
new MyTask("string2").execute();
}
if(checkBox3.isChecked()) {
new MyTask("string3").execute();
}
}
this is besically a logical error if we dry run this code it will
execute as many time as number of checked checkbox increases .
Suppose you do the checkbox1 to checked it will execute the async 1 time
while when you click checkbox2 it will execute checkbox1 async as well as checkbox2 async
and it be so on so change the condition on the button onclicklistner
Hi Since you are creating a new progressDialog every time therefore it is not getting dismissed. Create only one and keep variable at common place . For example
#Override
protected void onPreExecute() {
super.onPreExecute();
if(progressDialog!=null){
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setMessage(getString(R.string.message));
progressDialog.setIndeterminate(true);
progressDialog.show();
}
}
What are you doing in "doInBackground" method please write that code as well.
And what is "risultato" and "errori" refer to.
Related
i have an asynctask but if i implement a Thread.Sleep , then my app crashes , i dont know why, in onPreExecute i can see my first message and then after two secs it appears the other one i put in doInBackground , but its not working
private class sendMail extends AsyncTask<Void, Void, Void> {
protected void onPreExecute() {
dialog.setMessage("Please wait...");
dialog.show();
}
// automatically done on worker thread (separate from UI thread)
#Override
protected Void doInBackground(Void... voids) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
dialog.setMessage("Downloading files...");
new BackgroundTask().execute();
//MY DOWNLOADING METHODS STUFF
And then i dismiss this dialog somewhere else
Log
An error occurred while executing doInBackground()
You cannot access the UI elements from a background thread you can update the progressbar in onProgressUpdate, most importantly you need to publishProgress(value) in doInBackground and update using onProgressUpdate. Read more about the AsyncTask here.
Example code:
class MyTask extends AsyncTask<Integer, Integer, String> {
#Override
protected String doInBackground(Integer... params) {
for (; count <= params[0]; count++) {
try {
Thread.sleep(1000);
publishProgress(count);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return "Task Completed.";
}
#Override
protected void onPostExecute(String result) {
progressBar.setVisibility(View.GONE);
txt.setText(result);
btn.setText("Restart");
}
#Override
protected void onPreExecute() {
txt.setText("Task Starting...");
}
#Override
protected void onProgressUpdate(Integer... values) {
txt.setText("Running..."+ values[0]);
progressBar.setMessage("Downloading files...");
progressBar.setProgress(values[0]);
}
}
Use UI thread to show dialog message in doInBackground refer this https://stackoverflow.com/a/15757788/6626966
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
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.
Am getting exception when the user continuously clicking the button on which am calling the async task.
So is there any way to cancel the execution of first async task execution on second time pressing the button.
I hope u understand the problem.
The codes am using is given below.
On button click am using the following code
GetData obj= new GetData();
String urls="http://pathramonline.com/?cat=46";
obj.execute(urls);
My async task
public class GetData extends AsyncTask<String, Void, String>{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
BufferedReader reader =null;
String data =null;
try{
HttpClient client = new DefaultHttpClient();
URI uri=new URI(params[0]);
HttpGet get =new HttpGet(uri);
HttpResponse response= client.execute(get);
InputStream stream=response.getEntity().getContent();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer =new StringBuffer("");
String line="";
String newLine= System.getProperty("line.separator");
while((line=reader.readLine())!=null){
buffer.append(line+newLine);
}
reader.close();
data = buffer.toString();
return data;
}
catch(URISyntaxException e){
e.printStackTrace();
}
catch(ClientProtocolException f){
f.printStackTrace();
}
catch(IOException g){
g.printStackTrace();
}
catch(Exception e)
{
//
}
finally{
if(reader!=null){
try{
reader.close();
}
catch(Exception e){
}
}
}
return null;
}
#Override
protected void onCancelled() {
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
//TextView t3=(TextView)findViewById(R.id.textView3);
if(result==null)
{
Intent home = new Intent(MainActivity.this,NoConnection.class);
MainActivity.this.startActivity(home);
MainActivity.this.finish();
}
//Some actions
}
}
I would suggest another method instead of cancelling the asynctask.
In your onPreExecute() method disable the button click
button.setEnabled(false);
And in onPostExecute() method enable back the button
button.setEnabled(true);
If you explicitly want to know that button is disabled then while the asynctask is being executed you can change the background color of the button to another color or background, so that the user will know that some function is being carried out and he needs to wait..
Another approach is
new AsyncTask<Void, Void, Void>() {
String result = "";
ProgressDialog progressDialog = null;
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Loading , Please wait...");
progressDialog.setIndeterminate(true);
progressDialog.setCanceledOnTouchOutside(false);
progressDialog.show();
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
String url = "your link comes here"
JSONObject jsonObject = jpass.getJSONFromUrl(url);
try {
//do your work here
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void a) {
// TODO Auto-generated method stub
progressDialog.dismiss();
if (result.equals("success")) {
//on success do some work here
}
else
{
//on failure do some work here
}
super.onPostExecute(a);
}
}.execute();
Instead of cancelling the AsyncTask just set your button's click listener to null and then again set it inside onPostExecute of your AsyncTask. It would be even better if you display a ProgressBar when your doInBackground() code is executing.
I want to create a progress dialog in android, keep it open for 2 seconds then close it.
Below is the code I have written:
package com.example.proressdialogtest;
import android.app.activity;
import android.app.ProgressDialog;
import android.os.bundle;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
ProgressDialog pg = new ProgressDialog(MainActivity.this, 4);
pg.show(MainActivity.this, null, "Searching...", false);
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
pg.dismiss();
}
When I run the code on my device, the ProgressDialog is opened and then it stays open, it does not close after 2 seconds. What am I doing wrong?
As per the answers below. I have added the onPreExecute() and onPostExecute() methods before and after the doInBackground method respectively.
Here is the code for the two methods.
ProgressDialog pd;
public void onPreExceute() {
pd = new ProgressDialog(MainActivity.this);
pd.show(MainActivity.this, "", "Searching...", false);
}
public void onPostExecute() {
pd.dismiss();
}
The problem still persists. The progress bar will not close.
You are calling sleep() on the UI Thread. Don't do this. Use runOnUiThread or an AsyncTask
Painless Threading
AsyncTask
I would use an AsyncTask. You will start the ProgressDialog in onPreExecute() then close it in onPostExecute(). It is a UI element so using it in doInBackground() will give you the error
This SO answer has a good example of using it
Edit:
Use this code
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final ProgressDialog pg ;
pg = ProgressDialog.show(MainActivity.this, null, "Searching...", false);
Thread timer=new Thread(){
public void run()
{
try {
sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
finally{
pg.dismiss();
}
}
};
timer.start();
}
}
You are pausing the UI thread by calling
Thread.sleep(2000);
Because Thread.sleep(x) will make the current thread sleep for x milli seconds
which is bad thing.
place
I don't know why
pg.dismiss() in finally block to make sure that progress dialog will be closed.
And also your Code won't run because you have missed
super.onCreate(savedInstanceState);
following code will work for you,
new AsyncTask<Integer, Integer, Boolean>()
{
ProgressDialog progressDialog = null;
#Override
protected void onPreExecute()
{
progressDialog = ProgressDialog.show(MainActivity.this, "",
"Loading...");
}
#Override
protected Boolean doInBackground(Integer... params)
{
if (params == null)
{
return false;
}
try
{
Thread.sleep(2000);
}
catch (Exception e)
{
return false;
}
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
}
}.execute();