Displaying ProgressDialog within a PreferenceActivity - java

I've got a quite interesting issue when I try to display a ProgressDialog (the simple, spinner type) within a onPreferenceChange listener.
public class SettingsActivity extends PreferenceActivity {
private ProgressDialog dialog;
public void onCreate(Bundle savedInstanceState) {
ListPreference pref= (ListPreference) findPreference("myPreference");
pref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
dialog = ProgressDialog.show(SettingsActivity.this, "", "Doing stuff...", true);
SystemClock.sleep(2000);
}
return true;
}
}
The ProgressDialog shows up, but not until the method (sleep in this case) has finished. What am I doing wrong?

You're sleeping on the main UI thread, which stops the operating system from handling your application's events. This will stop your app from redrawing and as you discovered, can prevent new windows from actually appearing.
Instead of sleeping, try this:
final ProgressDialog dialog = ProgressDialog.show(
SettingsActivity.this, "", "Doing stuff...", true);
new Handler().postDelayed(new Runnable() {
public void run() {
dialog.hide();
}
}, 2000);

You can use AsyncTask to run the function in a separate thread (see http://developer.android.com/resources/articles/painless-threading.html)
This is probably a bit unnecessary if you just want to invoke a sleep method, but should work even for other methods that otherwise would block the UI thread.
You could do something like this:
private class BackgroundTask extends AsyncTask<Integer, Integer, void> {
private ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = ProgressDialog.show(SettingsActivity.this, "", "Doing stuff...", true);
}
#Override
protected void doInBackground(Integer... params) {
sleep(params[0]);
}
#Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
}
}
And than call it using the code below:
new BackgroundTask().execute(2000);

Related

Progress bar not showing up till last moment

This is my first android app,
I am calling function result on button click but as its call to findTimeTable takes time i want to show a progress bar but for some reason progress bar fails to show up until last moment just before the dialog box is created which defeats my purpose of showing the progress bar for that time period. In-fact that last moment is only visible when i don't set their visibility back to what it was.
public void result(View view) throws IOException {
findViewById(R.id.loadingPanel).setVisibility(View.VISIBLE);
findViewById(R.id.chooseFile).setVisibility(View.GONE);
findViewById(R.id.chooseDay).setVisibility(View.GONE);
findViewById(R.id.chooseTime).setVisibility(View.GONE);
findViewById(R.id.findFaculty).setVisibility(View.GONE);
String n = findTimetable(index_day, index_time);
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("hello" +n);
builder.setCancelable(false);
builder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i){
}
});
final Dialog mDialog = builder.create();
mDialog.show();
findViewById(R.id.loadingPanel).setVisibility(View.GONE);
findViewById(R.id.chooseFile).setVisibility(View.VISIBLE);
findViewById(R.id.chooseDay).setVisibility(View.VISIBLE);
findViewById(R.id.chooseTime).setVisibility(View.VISIBLE);
findViewById(R.id.findFaculty).setVisibility(View.VISIBLE);
}
I found a relevant answer android progress bar not showing
but as i am not familiar with threads in programming i could not implement it properly on my code.
please help.
Use an AsyncTask for the heavy comupting and add the progress bar in its Pre/Post states, and if you choose to update the GUI from there you need to run that code on the UI Thread.
Example AsyncTask:
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
// Start progressbar
}
#Override
protected String doInBackground(String... params) {
// Computing goes here
return null;
}
#Override
protected void onPostExecute(String result) {
// Stop progressbar
UpdateMyGUI();
}
#Override
protected void onProgressUpdate(Void... values) {
// Update progressbar (?)
}
}
private void updateMyGUI(){
runOnUiThread (new Runnable() {
public void run() {
// Update GUI Here.
}
});
}

AsyncTask setMessage after some time android java

hi i have AsyncTask in my app but i am unable to change its setMessage
for example :-
private class ProgressTask1 extends AsyncTask<String, Void, Boolean> {
private ProgressDialog dialog;
public ProgressTask1(MainActivity mainActivity) {
context = mainActivity;
dialog = new ProgressDialog(context);
}
private Context context;
protected void onPreExecute() {
this.dialog.setMessage("Checking system...");
this.dialog.setCancelable(false);
this.dialog.setTitle("Please Wait...");
this.dialog.setIcon(R.drawable.ic_launcher);
this.dialog.show();
}
now i want that setmessage to change i tried adding it in doinbackground
protected Boolean doInBackground(final String... args) {
dothis1();
this.dialog.setMessage("one done...");
dothis2();
this.dialog.setMessage("two done...");
but this is making app force close and do not rate it low because i tried my best and searched forum but could able to fix this so asked for hand at this nice community :)
anybody can help ? :)
ERROR
05-13 23:36:34.899: E/AndroidRuntime(2454): Caused by:
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the
original thread that created a view hierarchy can touch its views.
ohmm, you should not update UI from background thread. To update UI, you can do by two ways:
1) Using publishProgress (Progress... values) and onProgressUpdate(...). To do that, you must change your AsynTask class:
private class ProgressTask1 extends AsyncTask<String, String, Boolean> {
//.......... //your init
#Override
protected Boolean doInBackground(String... params) {
//your background handle
//publish to change UI
String toShow = "your_string_here";
publishProgress(toShow);
//return ...; //your return value
}
#Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
//detect message and show it.
//this.dialog.setMessage(values[0]);
}
}
2) Using onPostExecute(....):
private class ProgressTask1 extends AsyncTask<String, Void, Boolean> {
//.......... //your init
#Override
protected Boolean doInBackground(String... params) {
//your background handle
//return ...;//your return value
}
#Override
protected void onPostExecute(Boolean aBoolean) {
super.onPostExecute(aBoolean);
String toShow = "your_string_here";
//this.dialog.setMessage(toShow);
}
}
You cannot update the UI from the background.
See AsyncTask.onProgressUpdate to update the UI based on your background progress. :D

Cannot resolve symbol AlertDialogActivity

So I'm just trying to create an Alert Dialog that is just a message (no buttons or titles). I want to display an alert dialog when a background task is running. The alert dialog will run on the UI thread.
Here's what I have done so far:
protected void onPreExecute() {
super.onPreExecute();
AlertDialog altDlg;
altDlg = new AlertDialog.Builder(AlertDialogActivity.this).create();
altDlg.setMessage("Retrieving Information. Please Wait");
altDlg.show();
}
I also tried doing this:
AlertDialog.Builder builder = new AlertDialog.Builder(this)
.setMessage("Retrieve Info. Please Wait").show();
The error I am getting with the first one is:
cannot find symbol 'AlertDialogActivity'
symbol: class AlertDialogActivity
location: class com.example.Device.Activity
The second attempt error says:
incompatible types: com.example.Device.Activity cannot be converted to android.content.Context
I'm not sure what I am doing wrong in either scenario. I just want to display a basic message when a background task is running and I was hoping the closest thing I can use is AlertDialog.
EDIT for how to set up AsyncTask properly:
Small background of what I want to do. I just want to read in a file, deserialize it and save it's contents to a db.
Right now I'm assuming I only need two activities.
One is my main activity:
public class MainActivity extends Activity {
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup);
final Button setup_button = (Button) findViewById(R.id.setup_button);
setup_button.setOnClickListener (new View.OnClickListener() {
public void onClick(View view){
setContentView(R.layout.retrieve_info);
}
});
}
}
Now the onClick event just moves to the new view that is supposed to display the message or alert dialog that says retrieving information. Please Wait. It displays the message while reading a file and saving to db. Once the file is read and saved, The message should disappear and say something like setup complete.
My second activity so far is:
public class RetrieveInfoActivity extends AsyncTask<Void,Void,Void> {
private ProgressDialog progressBar;
private void retrieveInfo(String fileName) {
try {
File file = new File(fileName);
Scanner scanner = new Scanner(file);
//Read all the lines until there are no more lines
while (scanner.hasNextLine()) {
scanner.nextLine();
//TODO: deserialize and save to db
}
scanner.close();
}
catch (FileNotFoundException e) { e.printStackTrace(); }
}
#Override
protected Void doInBackground(Void... params) {
retrieveInfo("test.txt");
return null;
}
protected void onPreExecute() {
super.onPreExecute();
progressBar.setIndeterminate(true);
progressBar.setCancelable(false);
progressBar.setMessage("Retrieve Information.Please wait");
progressBar.show();
}
#Override
protected void onPostExecute() {
progressBar.dismiss();
}
}
That's all I really have so far. I just need to understand how to set up this in Android conceptually.
Hope this makes sense.
Try this:
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
Instead of using an AlertDialog use a ProgressBar, it will do the trick for you.
private ProgressDialog progressBar;
#Override
protected void onPreExecute() {
super.onPreExecute();
progressBar.setIndeterminate(true);
progressBar.setCancelable(false);
progressBar.setMessage("Your message");
progressBar.show();
}
#Override
protected void onPostExecute(final String error_code) {
progressBar.dismiss();
}
Looks like you are extending AsyncTask and trying to use it as a context. That won't work as AsyncTask itself is nothing but an abstract class.
You need to create a custom constructor for your AsyncTask to fetch the Context:
public class MyTask extends AsyncTask<Void, Void, Void> {
private Context mCtx;
public MyTask(Context context) {
mCtx = context;
}
...
Then when starting your AsyncTask, pass the context:
new MyTask(this).execute();
Another way would be to make the AsyncTask an inner class and use YourActivity.this when creating the dialog. Example:
public class YourActivity extends Activity {
...
private class MyTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
AlertDialog dialog = new AlertDialog.Builder(YourActivity.this).create();
}
#Override
protected Void doInBackground(Void... params) {
...
}
}
}

Android progress dialog for Listview

I have an activity with a listview. When I call this activity the activity takes about 3-5 seconds to appear and display the listview. It looks as if the button has not been pressed to load the activity, i would like to display a progressdialog while this loads but can't figure it out.
ProgressDialog progress;
progress = ProgressDialog.show(this, "Loading maps!",
"Please wait...", true);
// sort out track array
getTracks();
progress.dismiss();
I did the above on the oncreate() of the activity with the listview but the dialog never shows?
What I would like is to show the progress dialog on Activity A when the button is pressed and then dismiss once Activity B is loaded and displayed?
Thanks
You need to implement AsyncTask or simple JAVA threading. Go with AsyncTask right now.
onPreExecute() - display dialog here
doInBackground() - call getTracks()
onPostExecute() - display tracks in ListView and dismiss dialog
For example:
private static class LoadTracksTask extends AsyncTask<Void, Void, Void> {
ProgressDialog progress;
#Override
protected void onPreExecute() {
progress = new ProgressDialog(yourActivity.this);
progress .setMessage("loading");
progress .show();
}
#Override
protected Void doInBackground(Void... params) {
// do tracks loading process here, don't update UI directly here because there is different mechanism for it
return null;
}
#Override
protected void onPostExecute(Void result) {
// write display tracks logic here
progress.dismiss(); // dismiss dialog
}
}
Once you are done with defining your AsyncTask class, just execute the task inside onCreate() by calling execute() method of your AsyncTask.
For example:
new LoadTracksTask().execute();
You can make progress Dialog like this :
onPreExecute(){
progressdialog = new ProgressDialog(MainActivity.this);
progressdialog.setMessage("Please wait while downloading application from the web.....");
progressdialog.setIndeterminate(false);
progressdialog.setMax(100);
progressdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressdialog.setCancelable(false);
progressdialog.show();
}
doInBackground(String... strings){
// here you code for downloading
}
onProgressUpdate(String... progress)
{
// here set progress update
progressdialog.setProgress(Integer.parseInt(progress[0]));
}
onPostExecute(String result)
{
progressdialog.dismiss();
}
Use something like this:
private static class MapLoader extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
progress.setVisibility(View.VISIBLE);
// make your element GONE
}
#Override
protected Void doInBackground(Void... params) {
// Load map processing
return null;
}
#Override
protected void onPostExecute(List<Document> result) {
progress.setVisibility(View.GONE);
adapter.setNewData(new_data);
adapter.notifyDataSetChanged();
}
}
In your onCreate() use:
listView.setAdapter(adapter);
new MapLoader.execute();

Android: “BadTokenException: Unable to add window; is your activity running?

I am opening a progressdialog with AsyncTask in doInBackground method the question is loading from database and after question successfully loaded the progress dialog box will be closed
but my problem is some time I am getting following error
android.view.WindowManager$BadTokenException: Unable to add window -- token android.view.ViewRoot$W#44757528 is not valid; is your activity running?
by doing some googling I have found that there may be i am holding on to a reference to a Context (either explicitly, or by creating a Dialog or Toast or some other dependent item) that has been destroyed (typically because you are using the onCreateDialog or you passed the Activity to some other process that didn't get destroyed when the Activity was destroyed).
So I have put below code that dismiss progressdialog in-case if activity is destroyed before dialog box is dismissed
protected void onDestroy() {
if (pdForNewQuestion != null)
pdForNewQuestion.dismiss();
super.onDestroy();
}
but I still face the issue. I am not destroying any activity but still the error suddenly comes sometimes and sometimes it works properly
the async code is below
// Start new question in every 60 seconds :)
new Thread(new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(1000);
mProgressStatus++;
} catch (Exception e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
public void run() {
mProgress.setProgress(mProgressStatus);
txtCountingNum.setText((timer--) + "\nSec.");
if (timer < 0) {
questionLoadWithAsyncTask();
}
}
});
}
}
}).start();
public void questionLoadWithAsyncTask() {
new AsyncTask<Void, Void, Void>() {
#Override
protected void onPreExecute() {
pdForNewQuestion = new ProgressDialog(QuizActivity.this);
pdForNewQuestion.setTitle("Please wait...");
pdForNewQuestion.setMessage("Question is loading...");
pdForNewQuestion.setCancelable(false);
pdForNewQuestion.setIndeterminate(true);
pdForNewQuestion.show();
}
#Override
protected Void doInBackground(Void... arg0) {
wordsCursor = dbHelper.getRandomWords();
return null;
}
#Override
protected void onPostExecute(Void result) {
if (pdForNewQuestion != null) {
pdForNewQuestion.dismiss();
}
}
}.execute();
}
Check whether the dialog is showing or not if dialog is showing then only dismiss like this..
#Override
protected void onDestroy() {
if (pdForNewQuestion != null) {
if (pdForNewQuestion.isShowing()) {
pdForNewQuestion.dismiss();
pdForNewQuestion = null;
}
}
super.onDestroy();
}
you are running infinite loop inside new Thread but not breaking the loop and stopping that Thread. It runs infinitely in the background even when activity goes background. try stopping the Thread once work is finished.
First of all why are you starting your AsyncTask inside a Thread? As i understand you are trying to start an AsyncTask every 60 seconds and populate a new question. There is a much better way to do this using only a Handler and AsyncTask.
Create a Handler and post Runnable which runs every seconds and depending on the result start your AsyncTask :
int mSeconds = 0;
Handler mHandler = new Handler();
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if(mSeconds == 60){
new QuestionLoader().execute();
mSeconds = 0;
}
mHandler.postDelayed(this, 1000);
mSeconds++;
}
}, 1000);
and you can create your AsyncTask like this :
private class QuestionLoader extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute(){
super.onPreExecute();
pdForNewQuestion = new ProgressDialog(MainActivity.this);
pdForNewQuestion.setTitle("Please wait...");
pdForNewQuestion.setMessage("Question is loading...");
pdForNewQuestion.setCancelable(false);
pdForNewQuestion.setIndeterminate(true);
pdForNewQuestion.show();
}
#Override
protected Void doInBackground(Void... params) {
wordsCursor = dbHelper.getRandomWords();
return null;
}
#Override
protected void onPostExecute(Void result){
super.onPostExecute(result);
if(pdForNewQuestion != null && pdForNewQuestion.isShowing()){
pdForNewQuestion.dismiss();
}
}
}
This is usually caused by your app trying to display a dialog using a previously-finished Activity as a context. Then check that the activity is not closed by some other apps or other triggers before showing the dialog
if (!isFinishing()) {
//showdialog here
}

Categories