In my code i have a boolean to install information to the database via preference. It works fine but the issue is now that have alot of information to add to the app and i get a black screen while the information is being added to the sqlite (only during installation). How can i add a progress spinner so the users will know the app is in the installation process. I am afraid they will think the app is broken when they stare at the black screen.
/** Insert list into db once */
if (pref.getBoolean("isFirst", true)) {
readBLContactsfromAssetsXMLToDB("list.xml");
pref.edit().putBoolean("isFirst", false).commit();
}
addQuickActions();
}
First you may use AsyncTask for doing processes that take long time. If you are not aware of it, it allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
But if you insist not to use that, then since you are blocking the UI thread, you cannot show the dialog and do your stuff at the same time. You need to have a background thread for the lengthy process, and show the progress dialog on the UI thread.
There are lots of examples of AsyncTaks online. Just for sample:
private class OuterClass extend Activity{
//....
#Override
public void onCreate(Bundle savedInstanceState) {
new performBackgroundTask ().execute();
}
//....
private class performBackgroundTask extends AsyncTask < Void, Void, Void >
{
private ProgressDialog dia;
// This method runs in UI thread before the background process starts.
#Override
protected void onPreExecute(){
// Show dialog
dia = new ProgressDialog(OuterClass.this);
dia.setMessage("Installing...");
dia.show();
}
#Override
protected Void doInBackground(Void... params) {
// Do all the stuff here ...
addQuickActions();
}
// Ececutes in UI thread after the long background process has finished
#Override
protected void onPostExecute(Void result){
// Dismiss dialog
dia.dismiss();
}
}
}
You may see How to display progress dialog before starting an activity in Android?
Hope this helps.
Related
I have an Android application with an AsyncTask which is responsible for downloading a file from the internet. This AsyncTask is executed when clicking on an item in a Listview. So I have a custom adapter and in the OnItemClickListener of the Listview, I start the download and execute the AsyncTask.
Now, my adapter contains the following code to start the AsyncTask named FileDownloader:
#Override
public void onClick(View view) {
try {
FileDownloader fd = new FileDownloader(activity);
// some irrelevant code here
String filepath = fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString()).get();
}
catch(Exception e) { e.printStackTrace(); }
}
Activity is a private field that is passed to the adapter in the constructor of the adapter:
public GameHistoryAdapter(Activity a, int selectedIndex) {
this.activity = a;
}
The FileDownloader class contains an OnPreExecute method where I want to show the progress dialog on the activity:
#Override
protected void onPreExecute() {
super.onPreExecute();
dialog = new ProgressDialog(activity);
dialog.setMessage("Downloading...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
}
But whatever I try, the dialog does not appear. When I create an alert dialog in the OnPostExecute method of the AsyncTask, the dialog will show.
#Override
protected void onPostExecute(String res)
{
super.onPostExecute(res);
dialog.hide();
new AlertDialog.Builder(activity)
.setTitle(activity.getString(R.string.save_pdf_title_text))
.setMessage(activity.getString(R.string.save_pdf_text) + PDFFileName)
.setPositiveButton(activity.getString(R.string.close_text), null)
.setIcon(android.R.drawable.ic_dialog_info)
.show();
}
Does anyone know why the dialog is not appearing on my activity?
Does anyone know why the dialog is not appearing on my activity?
Yes, the following line of code...
String filepath = fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString()).get();
Don't EVER use the get() method of AsyncTask. It will block the main / UI thread and makes the whole point of an AsyncTask redundant. In other words get() turns it into a synchronous process instead of an asynchronous one.
The fact you can show a dialog in onPostExecute(...) is simply because it will be called after the blocking call to get() has returned. This means the main / UI thread will no longer be frozen (blocked) and UI updates can be made once again.
Remove get() from your call to execute(...) and instead just use...
fd.execute("http://myurl.com/img.png", PDFFileName, GameHistoryAdapter.this.gameInfo.toString());
...then in your onPostExecute(...) method set you filepath variable to what it should be.
I don't know who added the get() method to AsyncTask but if I ever find them I'll have some serious words to say. It has little or no use and causes a lot of people a lot of confusion.
My app requires gps reading, so on the main thread I start a Thread that reads the GPS but I'm having trouble showing a dialog that says "Please wait". I tied also using a Handler, but that didn't work either. What's the best to control the "Please wait" dialog from the 2nd Thread? Thanks!
public void showWaitDialog() {
prgDialog = new ProgressDialog(context);
prgDialog.setTitle("Please wait.");
prgDialog.setMessage("Please wait.");
prgDialog.setCancelable(false);
prgDialog.show();
}
You can:
Define an Handler in your UI Thread (e.g. in the Activity) and then pass it to your thread. Now from the thread you call handler.post(runnable) to enqueue code to be executed on the UIThread.
Define a BroadcastReceiver in your Activity and from you thread send an Intent with the necessary information in the Bundle
Use an AsyncTask and the methods publishProgress(), onProgressUpdate() or onPostExecute() to inform the Activity of the progress or when the taask has finished
Use runOnUiThread.
It depends on your needs. For short-running asynchronous operations, AsyncTask is a good choice.
Why not use an AsyncTask. You can tell the Task on onPreExecute() to show the Please wait dialog, and then onPostExecute(Result result) you can remove the dialog. Those two methods are working on the UI thread while doInBackground(Params... params) is occurring in a background thread.
Example:
private class GetGPSTask extends AsyncTask<null, null, null>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
showWaitDialog(); <-Show your dialog
}
#Override
protected void doInBackground(null) {
//your code to get your GPS Data
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
HideDialogbox(); <-Code to hide the dialog box
}
}
Just remember to change the template types if you need to. Where it says AsynTask , the first value is passed to doInBackground, 2nd value is for progress value, 3rd value is a return value from doInBackground to onPostExecute.
As other answers have rightly suggested, you can preferably use AsyncTask. Here is an exampleof how to use it for your purpose: AsyncTask Android example. Otherwise you may use runOnUiThread method as well. From inside your second thread to make the changes on UI thread ( eg: Dialogs and Toasts). According to its documentation, it says:
It runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
For eg;
Your_Activity_Name.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
showWaitDialog();
}
});
See display progressdialog in non-activity class and Loading Dialog with runOnUiThread for update view on Android.
hope this helps.
i am using a custom listview with images in my app
and loading all data from a json url.
i have created a onscrollistener()
which automatically add data below the current data when user scrolls to the bottom of the listview.
But when my data is loading whole listview freezes for 2-3 sec.
I dont know whats wrong??
here is my code for AsyncTask
private class BackgroundLoadMore extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
// Showing progress dialog before sending http request
}
protected Void doInBackground(Void... unused) {
runOnUiThread(new Runnable() {
public void run() {
LoadData();
list.setOnScrollListener(new EndlessScrollListener());
}
});
return (null);
}
protected void onPostExecute(Void unused) {
// On completing background task
// closing progress dialog etc,.
}
You must be fetching the json data from url in main UI thread. This blocks the UI from being updated by system, and hence the freeze. Use AsyncTask to do such network tasks in background.
LoadData() should be called in a background thread, which is asynctask's doInBackground(). Your call runOnUIThread puts it back on the UI thread, and that you dont want. remove the runOnUIThread call from asynctask.
protected Void doInBackground(Void... unused) {
LoadData();
return (null);
}
protected void onPostExecute(Void unused) {
// On completing background task
// closing progress dialog etc,.
list.setOnScrollListener(new EndlessScrollListener());
}
Move LoadData(); out of
runOnUiThread(new Runnable() {
public void run() {}
};
doInBackground is performing in the worker thread, but in it you use runOnUiThread wich start a UI therad operations.
You have to load all the data from net in background thread and then in postExecute update your listview
You are probably loading your data inside the UI thread.
Since operations such as loading JSON data from the internet are slow (from 0.5-10 seconds is typical) then if you do that inside the main thread of your app, the user interface will stop responding for this time. You should use a Thread or AsyncTask to load the JSON data asynchronously and so keep the UI thread free to respond to user input (such as scrolling the list).
My suggestion is that you use an AsyncTask to load the data.
Here are some links:
AsyncTask documentation
AsyncTask example
See the accepted answer for this question to see an implementation
Edit
Put list.setOnScrollListener(new EndlessScrollListener()); and list.notifyDatasetChanged(); inside onPostExcecute();
I am loading around 100 soundpools of small sound which I need them through out application in an activity.
When this activity starts, the screen goes blank and the background loads after loading all soundpools.
How do make it display the background I which have already added in xml through out while loading soundpools?
Use AsyncTask to handle this.
private class MyBackgroundTask extends AsyncTask<String, Void, Boolean> {
#Override
protected void onPreExecute() {
//initialize views like progress dialog.
}
#Override
protected Boolean doInBackground(String... params) {
//Add code which you want to run in background.
//In your case, code to load sound pools
}
#Override
public void onPostExecute(Boolean success) {
//update UI with the result
}
}
And in onCreate method,
new MyBackgroundTask().execute();
I have a long running method that is called during onCreate, this method populates textviews so interacts with the UI, and updates maybe 70 labels (about 3-20 seconds depending on device).
I want to display a progressdialog as this method executes.
Ideally I want to fire my method on the UI thread once the Activity has been displayed and the progress is displayed, this I cannot do, the Activity won't paint until the method has finished.
I hoped to find an event which was fired after the activity was displayed, and I found the one below, but it still leaves the screen black until the method has finished.
#Override
public void onPostCreate(Bundle savedInstanceState)
I am normally a WP7 developer, and in .NET you add an event handler for onLoadComplete which is fired after the ui is displayed, but before the user has a chance to interact withthe UI, how do I do this in Android JAVA?
Thanks
Put a ProgressBar in the View.
Then in the onCreate() or onResume() method do this:
new Thread() {
public void run() {
yourLargeMethod();
}
}.start();
Now you can do this inside your method to update the progressBar
public void yourLargeMethod() {
// doSomething
...
runOnUiThread(new Runnable() {
public void run() {
// update the progress from the thread
progressBar.setProgress(x); // x is your progress, 0 <= x <= progressBar.getMax()
}
});
}