I have a main activity that launches a child activity using the following code:
Intent intent = new Intent();
intent.setClassName(MyChildActivity.class.getPackage().getName(), MyChildActivity.class.getName());
((Activity)context).startActivity(intent);
I am trying to perform a time-consuming task in the child activity and would like to display a ProgressDialog while I do so. My code looks like this:
private ProgressDialog _progressDialog;
private OnClickListener btn_onClick = new OnClickListener() {
public void onClick(View v) {
_progressDialog = ProgressDialog.show(
v.getContext(),
"Please wait",
"Performing task..."
);
TaskThread t = new ExportThread(v.getContext());
t.start();
}
};
private class TaskThread extends Thread{
private Context _context;
public TaskThread(Context context) {
_context = context;
}
private Handler _handler = new Handler() {
#Override
public void handleMessage(Message msg) {
_progressDialog.dismiss();
}
};
#Override
public void run() {
performTask(_context);
_handler.sendEmptyMessage(0);
}
}
For some reason, the ProgressDialog is not displaying. If I use that same code in the main activity, it works - but not in the child activity. In addition, the following code also fails to display the ProgressDialog (but the Toast does display):
private ProgressDialog _progressDialog;
private OnClickListener _btn_onClick = new OnClickListener() {
public void onClick(View v) {
_progressDialog = ProgressDialog.show(
v.getContext(),
"Please wait",
"Performing task..."
);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
_progressDialog.dismiss();
Toast.makeText(v.getContext(), "Done with progress dialog.", Toast.LENGTH_SHORT).show();
}
};
Any ideas out there? Are we not allowed to display a ProgressDialog from a child activity?
Thank you.
why use thread instead of async task?
Async task implements the method onProgressUpdate and publishProgress which makes it easy to display and update UI/progress dialogs.
Here is some example code: http://android-projects.de/2010/12/08/threading-in-android-apps-wir-entwickeln-einen-zahler/
Related
I want to show this dialog, while the thread tries to build up a connection, but the dialog will not show up when I press the button which starts this method.
public void add_mpd(View view) {
dialog = ProgressDialog.show(MainActivity.this, "", "Trying to connect...");
new Thread(new Runnable() {
public void run() {
try {
String child;
EditText new_mpd = (EditText) findViewById(R.id.new_mpd);
child = new_mpd.getText().toString();
mpd = new MPD(child);
children.get(1).add(child);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (MPDConnectionException e) {
e.printStackTrace();
}
}
}
).start();
adapter.notifyDataSetChanged();
dialog.dismiss();
}
It will not show up because the (blocking) work is done in another thread. That means, the start()-method of the Thread-class will not block.
Ergo, you show the Dialog, the Thread is started and the dialog is immediately dismissed (and therefore closed).
Put the call to dismiss() at the end of your run()-method and it should work just fine.
The above might be working for you, but you should not use the Thread-class directly. There are wrappers around it which are way more comfortable to use.
In Android, if you want to do long-term work off the UI-Thread, you should use an AsyncTask.
Additionaly, to build up on what Lukas said, you can look at this example.
http://www.helloandroid.com/tutorials/using-threads-and-progressdialog
public class ProgressDialogExample extends Activity implements Runnable {
private String pi_string;
private TextView tv;
private ProgressDialog pd;
#Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
tv = (TextView) this.findViewById(R.id.main);
tv.setText("Press any key to start calculation");
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
pd = ProgressDialog.show(this, "Working..", "Calculating Pi", true,
false);
Thread thread = new Thread(this);
thread.start();
return super.onKeyDown(keyCode, event);
}
public void run() {
pi_string = Pi.computePi(800).toString();
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
pd.dismiss();
tv.setText(pi_string);
}
};
}
I am building a project in which i use async task to show progress bar.
I am using get() method to wait the main thread so we can do the other task before .
but progress bar is showing after completion of doInBackground thered.
I Want to show the loading bar when the loading starts.
It will dismiss when onPostExecute calls.
public class TempConverterActivity extends Activity {
pojo p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b= (Button) findViewById(R.id.btn);
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
showResult();
}
});
}
private void showResult() {
try {
new LoadData().execute().get();
} catch (Exception e) {
Log.e("async brix--", e.getMessage());
}
runned();
}
private void runned() {
ArrayList<String> al = p.getData();
for (String str : al){
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_SHORT).show();
}
}
private class LoadData extends AsyncTask<Void, Void, Void> {
private final ProgressDialog dialog = new ProgressDialog(TempConverterActivity.this);
protected void onPreExecute() {
dialog.setMessage("Loading data...");
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
protected void onPostExecute(final Void unused) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
#Override
protected Void doInBackground(Void... params) {
p = new pojo();
new SoapParser(p);
return null;
}
}}
Please help . Thanks in advance.
You can try following code,
progDailog = ProgressDialog.show(loginAct,"Process ", "please wait....",true,true);
new Thread ( new Runnable()
{
public void run()
{
// your code goes here
}
}).start();
Handler progressHandler = new Handler()
{
public void handleMessage(Message msg1)
{
progDailog.dismiss();
}
}
Edited: In my previous answer I suggested using a Handler; however, AsyncTask eliminates the need to do this which I didn't spot.
Why do you feel the need to call AsyncTask.get()? This is a blocking call, and you call this from the UI thread, thus it is ultimately a race condition as to whether it or onPreExecute() is run first.
I see no reason why you should call get() in this context. You want to call runned() after the AsyncTask completes, but you could do this by launching a new thread from onPostExecute(). Alternatively you could do as you do now, using get(), but call that from a new thread instead of the UI thread.
final ProgressDialog Pdialog = ProgressDialog.show(SpinnerClass.this, "",
"Loading. Please wait...", true);
Thread ProgressThread = new Thread() {
#Override
public void run() {
try {
sleep(3000);
Pdialog.dismiss();
} catch(InterruptedException e) {
// do nothing
} finally {
}
}
};
ProgressThread.start();
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
The problem I have with this thread is that it sets the current tab before the progress dialog starts. What have i done wrong ?
I want the dialog to run and dismiss, and after thread is done set tab.
use AsyncTask for this
some hints:
public class BackgroundAsyncTask extends AsyncTask<Void, Integer, Void> {
int myProgress;
#Override
protected void onPostExecute(Void result) {
TabHost1 tab = new TabHost1();
tab.tabHost.setCurrentTab(2);
progressBar.dismiss();
}
#Override
protected Void doInBackground(Void... params) {
while(myProgress<100){
myProgress++;
publishProgress(myProgress);
SystemClock.sleep(100);
}
return null;
}
#Override
protected void onProgressUpdate(Integer p) {
progressBar.setProgress(p);
}
}
The thing is that,you are starting a thread which will not affect your main UI. So what eventually happens is that, your thread will run separately which will now allow the next lines of your code to be executed. So in your case,
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
these lines will be executed irrespective to your thread which is also getting executed simultaneously. So what you can do here is you can either go for AsyncTask or create handlers to handle this part of your code. You have to change your code like this.
Do this in your onCreate()
Handler handler;
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (msg.what == 0) {
Pdialog.dismiss();
TabHost1 TabHost1Object2 = new TabHost1();
TabHost1Object2.tabHost.setCurrentTab(2);
}
};
And now in your thread,call the handler like this,
final ProgressDialog Pdialog = ProgressDialog.show(SpinnerClass.this, "",
"Loading. Please wait...", true);
Thread ProgressThread = new Thread() {
#Override
public void run() {
try {
sleep(3000);
} catch(InterruptedException e) {
// do nothing
} finally {
handler.sendEmptyMessage(0);
}
}
};
this will allow your tabhost to wait until the thread gets executed and will come into view after thread finishes execution.
I am using this simple code
public class Main extends Activity {
private ProgressDialog progressDialog;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//bouton Exemples de prix
findViewById(R.id.button1).setOnClickListener(
new Button.OnClickListener() {
public void onClick(View v) {
//start the progress dialog
runDialog(4);
Intent myIntent = new Intent(getBaseContext(), Exemple_prix.class);
startActivity(myIntent);
}
}
);
}
private void runDialog(final int seconds)
{
progressDialog = ProgressDialog.show(this, "", "Chargement...");
new Thread(new Runnable(){
public void run(){
try {
Thread.sleep(seconds * 1000);
progressDialog.dismiss();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
The progressDialog doesn't show but it works if I disable
//startActivity(myIntent);
Your progress dialog is tied to the activity, so it shows on top of the first activity, then immediately you're starting the new activity which covers both the old activity and the progress dialog. Is there a particular reason why you're showing the progress dialog? If it's related to work in the second activity, you should show it there instead.
On a side note, don't create a new thread just to sleep like that. Just use postDelayed.
For the past few days, I haven't been able to solve an issue with my dialog box. I am running a thread to show the dialog box for 5000ms and removing it. and I am trying to show a toast("SUCCESS"). The problem is I am getting the dialog box for the second time also. I am new to android development and I need to solve this with Async Task so that I can delay the second thread and show a alert dialog.builder with a positive button instead of toast. I goggled a lot but I confused to to implement this
Here I am sending my credentials to server and while sending I am showing a progress dialog box for 5000ms and I want to have a separate thread in order to show the dialog.builder with a positive button.( When the user get a response in the logcat for that I should check the responsecode==1 or not from the logcat to show the builder)
plz someone help me to solve this with some code snippet if possible.
Thanks in advance.
this is the code where I need to implement Async task
Button signin = (Button) findViewById(R.id.regsubmitbtn);
signin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// showDialog(0);
t = new Thread() {
public void run() {
register();
try {
while (counter < 2) {
showmsg(0);
Thread.sleep(5000);
removeDialog(0);
// Toast.makeText(Register.this, "Registerd", Toast.LENGTH_LONG).show();
showmsg(1);
// toast.show();
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t.start();
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case 0: {
++counter;
dialog = new ProgressDialog(this);
if (counter == 1) {
dialog.setMessage("Registering...");
}
else {
String resultsRequestSOAP = "";
if (Log.v("TAG", String.valueOf(resultsRequestSOAP)) == 1)
;
{
Context context = getApplicationContext();
CharSequence text = "Registerd";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
dialog.setIndeterminate(true);
dialog.setCancelable(true);
return dialog;
}
}
return null;
}
public void showmsg(int actionsToBePerformedOnScreen) {
Message msg = new Message();
msg.what = actionsToBePerformedOnScreen;
handler.sendMessage(msg);
}
public Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0:
showDialog(0);
break;
case 1:
// clear all images in the list
removeDialog(0);
break;
}
};
};
Easy: show dialog onPreExecute, register() in doInBackground and hide dialog in onPostExecute. Finally, do new RegisterTask().execute() in your onclick.
private class RegisterTask extends AsyncTask<Void, Void, Boolean> {
private final ProgressDialog dialog = new ProgressDialog(YourClass.this);
protected void onPreExecute() {
this.dialog.setMessage("Signing in...");
this.dialog.show();
}
protected Boolean doInBackground(final Void unused) {
return Main.this.register(); //don't interact with the ui!
}
protected void onPostExecute(final Boolean result) {
if (this.dialog.isShowing()) {
this.dialog.dismiss();
}
if (result.booleanValue()) {
//also show register success dialog
}
}
}
Why you don't use Android AsyncTask?
For example:
public class MyPreloader extends AsyncTask<InputObject, Void, OutputObject>{
private Context context;
private ProgressDialog dialog;
public MyPreloader(Context context){
this.context = context;
}
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(context);
dialog.setMessage("Please wait...");
dialog.setIndeterminate(true);
dialog.show();
super.onPreExecute();
}
#Override
protected ResponseBase doInBackground(InputObject... params) {
InputObject input = params[0];
//some code for background work
}
#Override
protected void onPostExecute(OutputObject result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
super.onPostExecute(result);
}