I have a little problem, I hope U can help me;)
Trouble is, that ProgressDialog show only after loading run(), but I need to show it on start and showing it while loading some data. I put: "dialog = ProgressDialog.show(CategoriesListActivity.this,"Working...","Loading data", true);" in method run(), but the same. I print in Log.i() some info (int i++) and put title of ProgressDialog. Method work correctly, but don't show ProgressDialog. I have read some info that some thread block another thread (my created), that's why doesn't show progressDialog, but can't do anything. Thx.
public void run() {
/** getting there long execution **/
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
// stop and hide dialog
dialog.dismiss();
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_
dialog = ProgressDialog.show(CategoriesListActivity.this, "Working...",
"Loading data", true);
// start new thread where get long time execution
Thread thread = new Thread(this);
thread.start();
//wait while data is loading, 'cause I need use variable from calculation
// in "EfficientAdapter" later
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListView l1 = (ListView) findViewById(R.id.list);
l1.setAdapter(new EfficientAdapter(this));
}
That's done with the help of AsyncTask (an intelligent backround thread) and ProgressDialog
When the AsyncTask starts we raise a progressdialog with indeterminate state, once the task is finished we dismiss the dialog.
Example code
What the adapter does in this example is not important, more important to understand that you need to use AsyncTask to display a dialog for the progress.
private class PrepareAdapter1 extends AsyncTask<Void,Void,ContactsListCursorAdapter > {
ProgressDialog dialog;
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(viewContacts.this);
dialog.setMessage(getString(R.string.please_wait_while_loading));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
/* (non-Javadoc)
* #see android.os.AsyncTask#doInBackground(Params[])
*/
#Override
protected ContactsListCursorAdapter doInBackground(Void... params) {
cur1 = objItem.getContacts();
startManagingCursor(cur1);
adapter1 = new ContactsListCursorAdapter (viewContacts.this,
R.layout.contact_for_listitem, cur1, new String[] {}, new int[] {});
return adapter1;
}
protected void onPostExecute(ContactsListCursorAdapter result) {
list.setAdapter(result);
dialog.dismiss();
}
}
Related
I have 2 activities, 1 called MainActivity, and the other called Circle. I want to have a progress bar loading screen come up when I click a button on the MainActivity to launch a second one. Here is the code that I have at the moment but it just causes the app to crash.
public class LoadingScreenActivity 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 the separate thread
#Override
protected void onPreExecute()
{
//Create a new progress dialog
progressDialog = new ProgressDialog(LoadingScreenActivity.this);
//Set the progress dialog to display a horizontal progress bar
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
//Set the dialog title to 'Loading...'
progressDialog.setTitle("Loading...");
//Set the dialog message to 'Loading application View, please wait...'
progressDialog.setMessage("Loading application View, please wait...");
//This dialog can't be canceled by pressing the back key
progressDialog.setCancelable(false);
//This dialog isn't indeterminate
progressDialog.setIndeterminate(false);
//The maximum number of items is 100
progressDialog.setMax(100);
//Set the current progress to zero
progressDialog.setProgress(0);
//Display the progress dialog
progressDialog.show();
}
//The code to be executed in a background thread.
#Override
protected Void doInBackground(Void... params)
{
/* This is just a code that delays the thread execution 4 times,
* during 850 milliseconds and updates the current progress. This
* is where the code that is going to be executed on a background
* thread must be placed.
*/
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(850);
//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)
{
//close the progress dialog
progressDialog.dismiss();
//initialize the View
setContentView(R.layout.content_circle);
}
}
}
You can add some default view like progressbar in second activity XML that is visible by default. When you load data or whatever you do set it to view.GONE. Nice library like this :
https://github.com/81813780/AVLoadingIndicatorView
In your second_activity.xml use :
<com.wang.avi.AVLoadingIndicatorView
android:layout_gravity="center"
android:id="#+id/avloadingIndicatorView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:indicatorName="BallPulse"
app:indicatorColor="#color/myPrimaryColor"/>
Then in your activity onCreate() method :
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loader= (AVLoadingIndicatorView) findViewById(R.id.avloadingIndicatorView);
}
And finally when you finish the loading just use :
loader.setVisibility(View.GONE);
First create a common Class Utility for ProgressDialog to reuse the code
public class Utility {
public static ProgressDialog getProgressDialog(Context context) {
ProgressDialog progressDialog = new ProgressDialog(context,
R.style.TransparentDialog);
progressDialog.setCancelable(false);
progressDialog
.setProgressStyle(android.R.style.Widget_ProgressBar_Small);
progressDialog.setProgress(0);
return progressDialog;
}
}
Then Use the Above class in your activity or fragment. But you have to use to Intent for go to next activity. you can't directly set the next activity layout
public class LoadingScreenActivity extends Activity
{
//A ProgressDialog object
protected ProgressDialog dialog;
/** 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 the separate thread
#Override
protected void onPreExecute()
{
super.onPreExecute();
dialog = Utility.getProgressDialog(context);
dialog.setCanceledOnTouchOutside(false);
dialog.setCancelable(false);
if (dialog != null) {
dialog.show();
}
}
//The code to be executed in a background thread.
#Override
protected Void doInBackground(Void... params)
{
/* This is just a code that delays the thread execution 4 times,
* during 850 milliseconds and updates the current progress. This
* is where the code that is going to be executed on a background
* thread must be placed.
*/
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(850);
//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;
}
//after executing the code in the thread
#Override
protected void onPostExecute(Void result)
{
//close the progress dialog
dialog.dismiss();
// use intent here to go next activity
Intent i = new Intent(this,SecondActivity.class);
startIntent(i);
}
}
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) {
...
}
}
}
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();
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
}
Here's the situation: I've got some lengthy non-UI code that needs to be run in a ListActivity and then have this ListActivity update the UI to contain a the result of this lengthy method (the list). I need a ProgressDialog to be running until it's finished so the user has some feedback.
Here's the code:
public class SolutionListActivity extends ListActivity
{
private String[] solutions;
private String letters;
private ProgressDialog dialog;
private static Solver solver;
/** Called when the activity is first created.
* #param savedInstanceState
*/
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//Get the selected letters from LettersActivity
letters = getIntent().getStringExtra("letters");
dialog = ProgressDialog.show(this, "Please Wait...",
"Searching Words...", true);
new Thread()
{
#Override
public void run()
{
if (solver == null)
{
solver = new Solver(SolutionListActivity.this);
solver.readDictionary(0);
solver.readDictionary(1);
}
solutions = solver.solve(letters);
runOnUiThread(new Runnable()
{
#Override
public void run()
{
dialog.dismiss();
//Set up a UI List
setListAdapter(new ArrayAdapter<String>(SolutionListActivity.this, R.layout.list_item, solutions));
ListView lv = getListView();
lv.setTextFilterEnabled(true);
}
});
}
}.start();
The problem is my ProgressDialog won't dismiss and I can't be sure whether the solutions = solver.solve(letters); will be finished before the UI uses it in setListAdapter(new ArrayAdapter<String>(SolutionListActivity.this, R.layout.list_item, solutions));
Any advice you guys have would be helpful.
Thank You,
Calum
Have you tried AsyncTask? It´s built exactly for having threading AND be able to update things in your UI Thread.
Take a look here: http://developer.android.com/resources/articles/painless-threading.html