I'm trying to get a ProgressDialog to load my listview before displaying it but i'm getting a crash. Would there be a better way to implement this?
EDIT: Updated with the logcat error, forgotten about it.
List<String> internetArray = new ArrayList<String>();
private ProgressDialog p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView internetList = (ListView)findViewById(R.id.list);
p = ProgressDialog.show(this, "Please wait..", "Loading list..", true);
new Thread(){
public void run(){
//do some extreme work before creating list
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
internetArray.clear();
//p.dismiss();
}
}.start();
getPermissions(this);
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, internetArray);
arrayAdapter.sort(new Comparator<String>() {
public int compare(String object1, String object2) {
return object1.compareTo(object2);
};
});
internetList.setAdapter(arrayAdapter);
}
Without a logcat from a first glance this is the problem: p.dismiss();.
You are trying to dismiss a UI element, in your case the progress dialog from a background thread.
Although I am certain that this is the cause, you should post your logcat for more details.
EDIT: The above error should be taken under consideration, although the error appears in creating the dialog: MainActivity.this this can't be instatiated. You can try passing the actual context by this and not class context MainActivity.this.
p = ProgressDialog.show(this, "Please wait..", "Loading list..", true);
UPDATE: Perhaps in your line of code is working but you have to know that when you are trying to access a UI element from a background thread would cause memory leaks (you are not even trying to access it through runOnUIThread() method, this is serious according to my opinion).
I didn't say that you should not add it at all, but you should add it in the ui thread. To our problem now, did the this work? Because I don't see any new logcat or something... :)
Related
I am working on a program that searches the users phone for some date, which takes about 2-3 seconds. While it's computing I want to display a loading screen, so the user knows something indeed is happening. However, when I try to display a loading screen before the computations, nothing is displayed on the screen.
This is what I have:
ProgressDialog loading= new ProgressDialog(this);
loading.setTitle("Loading");
loading.setMessage("Please wait...");
loading.show();
//search stuff
loading.dismiss();
In addition to this, I have tried putting the ProgressDialog in a thread like the following,
new Thread(new Runnable(){
public void run(){
ProgressDialog loading= new ProgressDialog(this);//error here for "this"
loading.setTitle("Loading");
loading.setMessage("Please wait...");
loading.show();
}
});
//search stuff
but it fails due to the "this" keyword, I believe because its referring to an Activity and not a regular class, but I could be wrong...
How can I get the ProgressDialog to display properly?
Try to handle it in this way
mProgressDialog = ProgressDialog.show(this, "Please wait","Long operation starts...", true);
new Thread() {
#Override
public void run() {
//Do long operation stuff here search stuff
try {
// code runs in a thread
runOnUiThread(new Runnable() {
#Override
public void run() {
mProgressDialog.dismiss();
}
});
} catch (final Exception ex) {
}
}
}.start();
Use async task for heavy task. Put your progress dialog code in onPreExecute method progress dialog dismiss code in onPostExecute method and all your heavy task in doInBackground method.
try passing down the context on a new class with your progress bar (this goes on your main activity)
NAME_OF_YOUR_CLASS context = new NAME_OF_YOUR_CLASS(getApplicationContext());
and on your class call the method like this..(this goes on class)
public Networking(Context c) {
this.context= c;
}
dont forget to make context a field (private final Context context;)
hope this helps
also idk if this will work but try to extend AsyncTask and use methods to run your progress bar there.
I am developing my first Android App and I want to display progress dialog while user click on login button in my apps. so I integrated asynctask in apps, all operation like login logout successfully done but problem is that after successfully login this giving me error like LoginActivity has leaked window due to progress dialog. how to dismiss progress dialog and update the UI.
please refer following code and tell me some changes
following is the LoginActivity
public class LoginActivity extends SherlockActivity {
.................
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sessionmngr = new SessionManager(this);
//check the user login or not
if (sessionmngr.isLoggedIn()) {
Intent checkLoginIntnt = new Intent(this,ProjectFragActivity.class);
startActivity(checkLoginIntnt);
}
setContentView(R.layout.activity_login);
........
}
// onclick listener when click on login activity
public void LoginToBookingScape(View v) throws JSONException {
username = edtTxtUserName.getText().toString();
userpsw = edtTxtUserPsw.getText().toString();
if ((username.trim().length() > 0)&&(userpsw.trim().length() > 0)) {
JsonWebService jsonWebs = new JsonWebService();
jsonWebs.execute(loginUrl);
}else {
............
}
}
Following is the Inner class to extend AsyncTask in LoginActivity
private class JsonWebService extends AsyncTask<String,Void,String> {
private ProgressDialog dialogLogin;
#Override
protected String doInBackground(String... url) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
....
inStream = httpEntity.getContent();
.........
return jsonResp;
}
#Override
protected void onPostExecute(String jsonData) {
//get string data from doinBackground
try {
JSONObject jsonObj = new JSONObject(jsonData);
String key_login = jsonObj.getString(KEY_LOGIN);
if (key_login.equalsIgnoreCase("0")) {
.............
}else {
....
sessionmngr = new SessionManager(getApplicationContext());
sessionmngr.createLoginSession(id,jsonObj.getString(KEY_UNAME),
jsonObj.getString(KEY_UEMAIL));
dialogLogin = ProgressDialog.show(LoginActivity.this, "Bookingscape",
"Please Wait",true);
dialogLogin.setIcon(R.drawable.icon);
new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
Intent inteProj = new Intent(getApplicationContext(),
ProjectFragActivity.class);
startActivity(inteProj);
finish();
}
........
}
#Override
protected void onCancelled() {
dialogLogin.dismiss();
dialogLogin = null;
super.onCancelled();
}
}
}
I want ask one question here
Is above code optimize and reusable.
Thanks in advance
The problem is you are moving to new activity without dismissing the progress dialogue . this will cause leaked window error
I think you must move dialogLogin.dismiss(); form onCancelled()block to onPostExecute block in your code
you must do this before you are going to another activity . ie before
Intent inteProj = new Intent(getApplicationContext(),ProjectFragActivity.class);
startActivity(inteProj);
this line of code .I think this will solve your issue
one doubt : where is your onPreExecute ?? Usually i display progress code in that block and dismiss that in onPostExecute
Usually the flow is like this onPreExecute-->doInBackground --->onPostExecute
EDIT :
onPreExecute: Initialize your UI components (eg: Dialoges) .In your case ProgressDialog showed up
doInBackground : After onPreExecute block control goes to this block this will .Here the ProgressDialog continues it's work
onPostExecute : control come here after all background action .Here you can dismiss your ProgressDialog and goto your new activity.
Possibly Its Because of you are writing
Intent inteProj = new Intent(getApplicationContext(),
ProjectFragActivity.class);
startActivity(inteProj);
before dismissing dialog, means your dialog is still showing process even your activity changed. so just put your
dialogLogin.dismiss();
dialogLogin = null;
lines before this
Intent inteProj = new Intent(getApplicationContext(),
ProjectFragActivity.class);
startActivity(inteProj);
then this problem will get resolved.
I had this issue also and this is what caused it.
My app takes input and adds them to SQLite database. This is what I had:
public Item doInBackground(String...params) {
Item item = new Item();
try {
item.setItemName(params[0]);
item.setSupplierPhone(params[1]);
...
databaseHandler.addItem(item);
//Toast.makeText(mContext, "Item successfully saved.", Toast.LENGTH_SHORT).show();
databaseHandler.close();
} catch (SQLiteException e) {
Toast.makeText(mContext, "Error saving Item!", Toast.LENGTH_SHORT).show();
}
return item;
}
I think this was because I was trying to show a Dialog after execution path was already in onPostExecute()
It is also important to note that there are a lot of reasons why this exception is thrown.
A lot of them are discussed here
You need to dismiss the dialog before forwarding to next activity.
Use:-
dialog.dismiss();
Sorry, I am new to Android programming. I have an xml parser that I don't want running in the UI thread. I want to display a progressdialog while the parser is running in its own thread but I don't want the main thread to start the next Activity until the parser is finished. I have code but the progressdialog doesn't display for the full duration. In place of the while loop, i've tried parserThread.join() with the same results. Also, I want to avoid timing out the UI thread. Any help is appreciated.
My method that invokes the thread, followed by the class that implements Runnable:
private void parseGasStationData() {
gasStations = null;
StationParser sp = new StationParser(activity);
Thread parserThread = new Thread(sp);
parserThread.start();
while (parserThread.isAlive()) {
// do nothing
}
gasStations = sp.getList();
Log.v("Parser-Status", "xml parsed successfully: "
+ (gasStations != null));
}
public class StationParser implements Runnable {
private Activity activity;
private final ProgressDialog pd;
public StationParser(Activity activity) {
this.activity = activity;
pd = ProgressDialog.show(activity, "", "Parsing data...", true, false);
}
#Override
public void run() {
try {
runParser();
} catch (XmlPullParserException e) {
Log.e("Parser-Error", "XmlPullParserException", e);
e.printStackTrace();
} catch (IOException e) {
Log.e("Parser-Error", "IOException", e);
e.printStackTrace();
} catch (ParseException e) {
Log.e("Parser-Error", "ParseException", e);
e.printStackTrace();
}
pd.dismiss();
}
In android we use the AsyncTask class to make background operations an show the results. See the main document page here the first example seems pretty useful for you, just change the doInBackground method for your parser.
This code:
while (parserThread.isAlive()) {
// do nothing
}
needs to go. As long as you have that, you might as well not be using a separate thread at all. (In fact, it's worse, because it's a "busy wait" that hogs the CPU.)
The right way to do this is with a call-back. When the parsing thread is done, it can call post(Runnable) to run a process on the UI thread that will make the progress dialog go away. You can use AsyncTask to help with this. See the guide topic Processes and Threads for more information.
I'm trying to implement the code from showing dialog while loading layout by setContentView in background and http://developer.android.com/guide/appendix/faq/commontasks.html#threading to show a loading dialog while my activity is loading, but having difficulty.
I have class variables defined for the UI elements in my view, and also strings for the data which is loaded on another thread from the database:
private TextView mLblName, mLblDescription, etc...
private String mData_RecipeName, mData_Description...
I also have the handlers defined:
private ProgressDialog dialog;
final Handler mHandler = new Handler();
final Runnable mShowRecipe = new Runnable() {
public void run() {
//setContentView(R.layout.recipe_view);
setTitle(mData_RecipeName);
mLblName.setText(mData_RecipeName);
mLblDescription.setText(mData_Description);
...
}
};
In onCreate, I'm trying too show the dialog, then spawn the loading thread:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialog = ProgressDialog.show(this, "", "Loading. Please wait...", true);
setContentView(R.layout.recipe_view);
showData();
}
protected void showData() {
// Fire off a thread to do some work that we shouldn't do directly in the UI thread
Thread t = new Thread() {
public void run() {
mDatabaseAdapter = new ChickenPingDatabase(ShowRecipe.this);
mDatabaseAdapter.open();
mTabHost = getTabHost();
mLblName = (TextView)findViewById(R.id.lblName);
mLblDescription = (TextView)findViewById(R.id.lblDescription);
...
Cursor c = mDatabaseAdapter.getRecipeById(mRecipeId);
if(c != null){
mData_RecipeName= c.getString(c.getColumnIndex(Recipes.NAME));
mData_Description= c.getString(c.getColumnIndex(Recipes.DESCRIPTION));
...
c.close();
}
String[] categories = mDatabaseAdapter.getRecipeCategories(mRecipeId);
mData_CategoriesDesc = Utils.implode(categories, ",");
mHandler.post(mShowRecipe);
}
};
t.start();
}
This loads the data, but the progress dialog isn't shown. I've tried shuffling the call to spawn the separate thread and show the dialog around, but can't get the dialog to show. It seems this is a fairly common request, and this post seemed to be the only answered example of it.
EDIT: For reference, a blog post demonstrating the way I eventually got this working.
Since what you want is pretty much straight-forward, I would recommend that you use an AsyncTask. You can control the showing/hiding of the dialog in onPreExecute() and onPostExecute(). Check out the link, there's a good example in there.
I'm trying to create a ProgressDialog for an Android-App (just a simple one showing the user that stuff is happening, no buttons or anything) but I can't get it right. I've been through forums and tutorials as well as the Sample-Code that comes with the SDK, but to no avail.
This is what I got:
btnSubmit.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
(...)
ProgressDialog pd = new ProgressDialog(MyApp.this);
pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
pd.setMessage("Working...");
pd.setIndeterminate(true);
pd.setCancelable(false);
// now fetch the results
(...long time calculations here...)
// remove progress dialog
pd.dismiss();
I've also tried adding pd.show(); and messed around with the parameter in new ProgressDialog resulting in nothing at all (except errors that the chosen parameter won't work), meaning: the ProgressDialog won't ever show up. The app just keeps running as if I never added the dialog.
I don't know if I'm creating the dialog at the right place, I moved it around a bit but that, too, didnt't help. Maybe I'm in the wrong context? The above code is inside private ViewGroup _createInputForm() in MyApp.
Any hint is appreciated,
you have to call pd.show before the long calculation starts and then the calculation has to run in a separate thread. A soon as this thread is finished, you have to call pd.dismiss() to close the prgoress dialog.
here you can see an example:
the progressdialog is created and displayed and a thread is called to run a heavy calculation:
#Override
public void onClick(View v) {
pd = ProgressDialog.show(lexs, "Search", "Searching...", true, false);
Search search = new Search( ... );
SearchThread searchThread = new SearchThread(search);
searchThread.start();
}
and here the thread:
private class SearchThread extends Thread {
private Search search;
public SearchThread(Search search) {
this.search = search;
}
#Override
public void run() {
search.search();
handler.sendEmptyMessage(0);
}
private Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
displaySearchResults(search);
pd.dismiss();
}
};
}
I am giving you a solution for it,
try this...
First define the Progress Dialog in the Activity before onCreate() method
private ProgressDialog progressDialog;
Now in the onCreate method you might have the Any button click on which you will change the Activity on any action. Just set the Progress Bar there.
progressDialog = ProgressDialog.show(FoodDriveModule.this, "", "Loading...");
Now use thread to handle the Progress Bar to Display and hide
new Thread()
{
public void run()
{
try
{
sleep(1500);
// do the background process or any work that takes time to see progress dialog
}
catch (Exception e)
{
Log.e("tag",e.getMessage());
}
// dismiss the progress dialog
progressDialog.dismiss();
}
}.start();
That is all!
Progress Dialog doesn't show because you have to use a separated thread. The best practices in Android is to use AsyncTask ( highly recommended ).
See also this answer.
This is also possible by using AsyncTask. This class creates a thread for you. You should subclass it and fill in the doInBackground(...) method.