I have a problem with progress dialog on opening an activity (called activity 2 in example).
The activity 2 has a lot of code to execute in this OnCreate event.
final ProgressDialog myProgressDialog = ProgressDialog.show(MyApp.this,getString(R.string.lstAppWait), getString(R.string.lstAppLoading), true);
new Thread() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
showApps();
}
});
myProgressDialog.dismiss();
}
}.start();
The showApps function launch activity 2.
If I execute this code on my button click event on activity 1, I see the progress, but she doesn't move and afeter I have a black screen during 2 or 3 seconds the time for android to show the activity.
If I execute this code in the OnCreate of Activity2 and if I replace the showApps by the code on OnCreate, Activity1 freeze 2 seconds, I don't see the progress dialog, and freeze again 2 seconds on activity 2 before seeing the result.
I had the same issue and using an AsyncTask is working for me.
There are 3 important methods to override in AsyncTask.
doInBackground : this is where the meat of your background
processing will occur.
onPreExecute : show your ProgressDialog here ( showDialog )
onPostExecute : hide your ProgressDialog here ( removeDialog or dismissDialog
)
If you make your AsyncTask subclass as an inner class of your activity, then you can call the framework methods showDialog, dismissDialog, and removeDialog from within your AsyncActivity.
Here's a sample implementation of AsyncTask:
class LoginProgressTask extends AsyncTask<String, Integer, Boolean> {
#Override
protected Boolean doInBackground(String... params) {
try {
Thread.sleep(4000); // Do your real work here
} catch (InterruptedException e) {
e.printStackTrace();
}
return Boolean.TRUE; // Return your real result here
}
#Override
protected void onPreExecute() {
showDialog(AUTHORIZING_DIALOG);
}
#Override
protected void onPostExecute(Boolean result) {
// result is the value returned from doInBackground
removeDialog(AUTHORIZING_DIALOG);
Intent i = new Intent(HelloAndroid.this, LandingActivity.class);
startActivity(i);
}
}
AFAIK you cannot preload any activity with progress dialog displayed. Are you testing on a real device or in emulator?
I've seen workarounds that opened an activity with a ViewFlipper having a progress animation in the center, and in the next View, it was loaded an activity, but it's not something is recommended and hard to implement to work as you wish.
GeeXor
I would suggest you to avoid performing lots of operations in Activity 2's OnCreate.Writing lots of operations in OnCreate is a reason for the black screen between activities.So perform those operations asynchronously using AsyncTask or in a Thread (or write them in onStart if they are unavoidable).
The other suggestion is to start another progressDialog in activity 2's onCreate which will run until all of your data is loaded & user will know that something is happening in background.
this is what i would do. create a handler on the ui thread, start the background processing thread and then show the progressdialog. when the background thread has finished it's work get it to post a runnable on the ui thread via the handler to dismiss the dialog.
Related
I have a loading activity which makes few requests to server and converts data.
And layout of this activity is just simple logo image and progressBar.
All my operations were made in onCreate() and according to received request from server I start different activities:
if (request == 1) { start activity A}
else { start activity B}
The problem is loading takes 2-3 sec and operations are made even before onResume(), before activity's view come to UI.
So its just blank activity which does some work.
How can I ensure that those operations are made only after activity complete its creation?
If i clearly understand you you want to start activity 0 in which onCreate function is doing internet requests and after getting feedback from it you decide to call activity A or B. Is that correct? If yes you need to do network request in backgroud so your user interface thread doesnt freez. You can use AsyncTask for example and on it's onPostExecute method decide to fire acitivty A or B
EDIT
private class YourAsyncTask extends AsyncTask<String, Long, String> {
protected Long doInBackground(String... params) {
//here is background thread work calling net API request, hard working etc... but you can't touch UserInterface thread, since we are in background
//here call your API and parse answear
String ret = flag
return flag;
}
protected void onProgressUpdate(Long... progress) {
}
protected void onPostExecute(String result) { //here you are getting your flag from doInBackground as a result parameter
// this is executed after doInBackground, fired automatically and run on User interface thread here you can for example modify layout so you can run activity A OR B
}
}
and if you have your logic in AsyncTask you can run it from onCreate for example it doesn't matter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
new YourAsyncTask().execute();
}
So you layot will be displayed and after executed your onPostExecute will be called
You need to move that server call off the main ui thread. Use an IntentService or something similar.
What I understand from this question, you must be using AsyncTask or Service to connect to server. You put the main thread in while loop and AsyncTask or Service is doing the required operation for you. After operation is complete, it will break out of while loop and then use if/else loop and decide which activity to start next.
Something like this:
public void onCreate(Bundle savedInstanceState)
{
boolean isDone = false;
// initialization code here
// start AsyncTask
BackgroundThread.execute(params);
while(!isDone)
{
Thread.sleep(1000); // 1 sec
}
}
doInBackground()
{
// your code
isDone = true;
}
onPostExecute() is executed on main thread, not on background thread.
so I am coming across a weird problem I cant find an explaination for. I have an async task in which in its doBackground method does a wait until a certain variable is set then the "wait" is notified
private class TestAsyncTask extends AsyncTask<Void, Object, Boolean> {
#Override
protected void onPreExecute() {
Log.d("Test1");
}
#Override
protected Boolean doInBackground(Void... params) {
Log.d("Test2");
while (nextCardToPlay == null) {
wait();
}
Log.d("Test3");
}
}
Activity A:
protected void onCreate(){
a = new TestAsyncTask().execute();
}
protected void onPause(){
a.cancel()
}
So as you can see when the activity starts, the asyncTask is started. When activity is closed the asyncTask is supposed to be cancelled.
What I noticed is that if I open the activity, close it, and reopen it again then the asynctask is created and in wait mode (never cancelled). No problem. Whats confusing is that when I start the activity (while the stale asyncTask is there), then it seems a new asyncTask is started ( because the logs from OnPreExecute are called) however the doInBackground in the nextAsyncTask is not executed because the Test2 log is not showing.
Any idea why?
This behavior is not at all weird if you look at the documentation, which states the AsyncTasks run on a single background thread, i.e. sequentially. If you really want your tasks to run on parallel worker threads, then use the executeOnExecutor() method instead of a simple execute() and pass it the AsyncTask.THREAD_POOL_EXECUTOR parameter.
While I'm updating my database I want to display a progress dialog. My problem is that the ProgressDialog is getting late to appear,after 4-5 seconds, then appears and disappears very fast, it stays on screen few milliseconds almost you can't see it, then new data are shown in the list immediately. This makes me think that the ProgressDialog is waiting for database to be updated(it doesn't take much, about 4,5 seconds) and then it shows on the screen but is dismissing very fast. I would like the ProgressDialog appear immediately I press the 'Update' button and stay on the screen about 4-5 seconds.
class MyAsyncTask extends AsyncTask<Void, Void, Void>{
ProgressDialog myprogsdial;
#Override
protected void onPreExecute(){
myprogsdial = ProgressDialog.show(MyActivity.this, null, "Upgrade", true);
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
RefreshDataBase();
}
});
return null;
}
#Override
protected void onPostExecute(Void result){
myprogsdial.dismiss();
}
}
When I call it, new MyAsyncTask().execute();
Ok I think that this
runOnUiThread(new Runnable() {
is causing this behavior.
doInBackground() executes your code in a new thread to the main UI thread. You are then putting the code to execute in this thread back into the main one causing the progress dialog to be delayed at the end and then in postExecute() it gets closed immediately.
A good asyntask tutorial can be found here.
You must not use runOnUiThread. What you're basically did is:
Started new non-ui thread
From this new non-ui thread you posted a long running task to UI thread.
Exited from non-ui thread.
Your ui thread now executes long-running operation (RefreshDataBase) and blocks the UI.
You should call RefreshDataBase() directly. And if this method touches UI, you have to refactor it.
I have solved it, using this answer of Vladimir Ivanov.
I have separated the functionality by the appearance.
I have kept the functionality(downloading new data) in doInBackground() and in onPostExecute() I updated the list: get the new adapter,called setListAdaper() and notifyDataSetChanged.
Of course, I quit using runOnUiThread(). Thanks to all for hints.
In my app I am doing some intense work in AsyncTask as suggested by Android tutorials and showing a ProgressDialog in my main my activity:
dialog = ProgressDialog.show(MyActivity.this, "title", "text");
new MyTask().execute(request);
where then later in MyTask I post results back to activity:
class MyTask extends AsyncTask<Request, Void, Result> {
#Override protected Result doInBackground(Request... params) {
// do some intense work here and return result
}
#Override protected void onPostExecute(Result res) {
postResult(res);
}
}
and on result posting, in main activity I hide the dialog:
protected void postResult( Result res ) {
dialog.dismiss();
// do something more here with result...
}
So everything is working fine here, but I would like to somehow to update the progress dialog to able to show the user some real progress instead just of dummy "Please wait..." message. Can I somehow access the progress dialog from MyTask.doInBackground, where all work is done?
As I understand it is running as separate Thread, so I cannot "talk" to main activity from there and that is why I use onPostExecute to push the result back to it. But the problem is that onPostExecute is called only when all work is already done and I would like to update progress the dialog in the middle of doing something.
Any tips how to do this?
AsyncTask has method onProgressUpdate(Integer...) that you can call each iteration for example or each time a progress is done during doInBackground() by calling publishProgress().
Refer to the docs for more details
you can update from AsyncTask's method onProgressUpdate(YOUR_PROGRESS) that can be invoked from doInBackground method by calling publishProgress(YOUR_PROGRESS)
the data type of YOUR_PROGRESS can be defined from AsyncTask<Int, YOUR_PROGRESS_DATA_TYPE, Long>
How to add tabbar in doinbackground asynctask in android? or how to run splash screen in thread? I want to show a progress dialog or splash screen until tab bar is loaded from calling tabbar class I am calling webservices and parsing the value takes time, for few mins mean time, I have to show progessbar or splash screen. Can anybody tell me how to implement this? Can anybody give sample code?
I tried but its not working
dlg = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false);
Thread splashThread = new Thread() {
#Override
public void run() {
try {
sleep(100000);
} catch (InterruptedException e) {
// do nothing
} finally {
}
}
};
splashThread.start();
you cannot touch anything of the main ui thread from a background thread, in order to do that you have to use a handler who manages the synchronization between background thread and ui main thread.
the better way is subclassing the AsyncTask, doing this, you already have methods who works on background and methods who work on the ui. With this, you can perform the background operation and inmediatly shows the result...
public class AsynchronousTask extends AsyncTask<Runnable, String, Result> {
//method executed automatically in the ui event before the background thread execution
#Override
protected void onPreExecute() {
//show the splash screen and add a progress bar indeterminate
}
//method executed automatically in the ui event AFTER the background thread execution
#Override
protected void onPostExecute(Result result) {
//hide the splash screen and drop the progress bar or set its visibility to gone.
}
//method executed in a background event when you call explicitly execute...
#Override
protected Result doInBackground(Runnable... tasks) {
Result result;
if(tasks != null && tasks.length > 0){
for (Runnable runnable : tasks) {
//publishProgress( ... );
runnable.run();
//result = ...
//publishProgress( ...);
}
}
return result;
}
}
http://developer.android.com/reference/android/os/AsyncTask.html
read more here
hope this helps...