When my activity is being closed, I serialize the application state data to file to give me a chance to reload the state if the app gets killed by the system.
This approach (saving and restoring state) works fine. But, sometimes, when the process was killed, and depending on the amount of data to load, the loading state process can least some seconds to complete.
So, I can't load the state on a separeted thread because my activity will crash if the data isn't there on the onLoad.
So, I'd like to display a progress dialogue while loading the content, but, ensure that the Activity's onLoad method will be called only after the loading state process.
Does anybody knows how could I achieve this? Thanks a lot.
Hmmm.. could you Override the onLoad() function, then add a boolean that states whether you're displaying the dialog or not. If the dialog is being displayed (the boolean is true), don't let onLoad() do anything; otherwise, carry on as usual. That way once the dialog is dismissed, you can set the boolean to false again, and if onLoad() isn't called by default afterwards, perhaps you could manually call it? This is just an idea.
In other words: the dialog can be displayed using an AsyncTask. In the onPreExecute() method, set the boolean to true, do everything you need in doInBackground(), and in onPostExecute(), set the boolean to false and call onLoad().
On a side note... do you mean onCreate() or onResume()? I've actually not heard of onLoad(), unless this is a function you created.
Related
My Problem: Is it possible to prevent an activity to call OnResume() when it is being created? As I saw after the OnCreate() and onStart() method runs, the next one is the onResume(), although I only want to have it when I resume the activity from the paused state.
Why do I need this: I launch my activity (FragmentActivity, so lets say OnPostResume() ) starting with a thread which takes about 2-3s to be ready getting data from an external database. After the thread is done, I call a method which needs these data and I want to call it everytime that activity gets visible. The thread runs only when the FragmentActivity is created (onCreate()), and I cannot put the method into the onResume() because onResume() would be running way before the thread would finish its task. So it would receive not-ready data.
Anyone has a better idea?
Not sure of the exact application of this but I'll make a suggestion.
If you use an AsyncTask, you can send it off to get the data you need and in the onPostExcecute() method you can call your method that requires the data or update the view as needed. (It runs on the UI thread)
If you happen to already have the data you need in certain scenarios you could also bypass the AsyncTask and directly update the view.
This AsyncTask can be triggered in the onResume() method.
If I'm missing something, please let me know and I can adjust my suggestion.
I didn't understand the purpose of this, but here's a possible solution:
If you only wish to get the even of onResume on states that didn't have the onCreate before, just use a flag.
In the onCreate, set it to true, in the onResume check the flag (and also set it to false). if it was true, it means the onCreate was called before.
I personally would prefer to check if the result available, rather than always executing the getter-code in onResume. If the user somehow resumes your activity before the background thread is finished, you'd have a call on onResume, but don't want to display a result.
Maybe it would be a good idea to calculate/fetch the values in the thread, and let the thread return immediately (and cause the values to get filled in) if the values are already cached somewhere. That way you'd only have one entry point (the thread) for updating your UI instead of two (the thread and the onResume method).
I have a Async Task that creates a HashMap to create a Adapter to populate ListView. I have a progress dialog that shows during doInBackground method.In onPostExecute() method, I dismiss the progress dialog and call a method that populates my listview with the list of items saved in doInBackground method.
This works fine. But I noticed something strange:
The issue I see is, if I lock the screen when the progress dialog is about to be dismissed (in onPostExecute), the listview does not display, even though it has non-empty items in it. I verified it in logcat messages and when I debugged.
Is there a possibility that a screen lock (I do this my pressing power button once) blocking UI thread? How can I resolve the issue and make sure ListView displays its items?
Code for onResume():
#Override
protected void onResume(){
super.onResume();
if(MyAdapter !=null){
pull_listView.setAdapter(MyAdapter);//pull_listView is listview
MyAdapter.notifyDataSetChanged();//MyAdapter is the adapter
}
}
This situation illustrates the downside of using AsyncTask to do background processing. In some cases, an IntentService may be a better choice, especially if you think the background work is going to take some time. An AsyncTask ties the background work to the current Activity, while an IntentService is completely decoupled.
The Android training class Running in a Background Service shows you how to set up an IntentService, request work, and notify your Activity when the work is done. Passing data from the IntentService to the Activity is a bit more complicated, but there are options.
onStop() will be called when your screen goes out as per the Activity Lifecycle. You could override onStart() or onResume() and put a check in there to see if your data has been populated. If not, populate. You may even want to overide 'onStop()' to save data if the screen goes out.
Edit
In this particular situation, I would think onResume() or onStart() would be fine but onResume() is usually the safest because it is guaranteed to get called before the Activity is shown as illistrated in the link I gave. What kiind of a check you want to use is up to you and depends on how you handle evrything. However, if your AsyncTask is an inner class of your Activity class the you could simply create a boolean member variable, say boolean isDone=false; change this to true in your doInBackground() or onPostExecute() then your onResume() knows the data Is loaded. If its false then you can try to get data again. Hope this makes sense and can help
Basically when a menu item is pressed in my app it takes the user to a new screen.
But now i want to get a little bit of data online(a time/date) that will display somewhere on the page once it gets the data.
At the moment the new screen doesnt load until the app gets the data which leaves a couple of second pause instead of loading the screen instantly and then showing the downloaded data when it finally has it.
Ive tried using the onStart method since that gets called after onCreate so i thought the page would be created and displayed and then onStart gets called but that doesnt happen, theres still lag between it loading because its getting the data online and then displays the page with it already loaded.
How can i sort this?
Thanks
For any kind of loading operation you should consider using the AsyncTask in combination with the ProgressDialog in order to inform your user that you're performing something in the background.
Remember that you can only interact with the UIThread in the onPreExecute() and onPostExecute() method of your AsyncTask.
So in your case you'll probably want to fire the AsyncTask in the onCreate() method of your Activity, showing the ProgressDialog in the onPreExecute() method and then showing your information and hiding your ProgressDialog in the onPostExecute.
It's pretty much impossible to eliminate this lag you're talking about. So you better just handle it appropriately.
Hope this helps answers your question.
Im building an Android application. It parses a feed which is stored in a DB. Each activity of the app is able to get this data from the DB.
Every activity can also call the Service, and make it refresh the data. When this is done I would like to display a loader. While the Service is downloading, the user is still free to navigate between activities. My question is; how can I display a loader that runs in all activities the user navigates to?
Thanks a lot :)
Here's what I would try to do since it seems to be an uncommon task to me:
I would try to setup a translucent PopupWindow which contains a progress indicator. I would trigger / dismiss this popup to be displayed / or not whenever there's a need to indicate the loading progress...
You could try something like:
Place a "global loader view" in all your activities.
When you start/return to an activity, fire an AsyncTask which will be used to handle updates of the global loader
Override onPreExecute() to prepare the global loader (e.g. setting its state to the current level if the service has been downloading for a while)
Override onProgressUpdate() and use it to update the state of the global loader by asking the Service for the current state (load percentage or something)
In doInBackground you implement:
while( service.isLoading() ) {
publishProgress( service.getLoadPercentage() )
// Maybe add a Thread.sleep() here.
}
Override onPostExecute to set the visibility of the global loader to View.GONE.
You might need to implement a way of killing the AsyncTask if the user switches away from the activity when the loading is not finished yet.
I have two static tables with about 500 records each which provide lookup material for some ListViews in my app. When the app first starts and the tables are created I run a process to populate the tables which takes less than a minute but I've been looking to run the process in background using Async Task with a progress dialog letting the user know what is happening.
My concern is that while the process is running and the data is being added and then the user tilts the phone the process will cancel. What would be the state of my database then? Is Async Task the best solution for this or should I use Threading?
So when you rotate or change the orientation of the phone, the activity is the only thing destroyed. You don't necessarily have to get rid of the async task. In fact it will live on. Just don't let another task come in and work on it ad-hocly.
So if you want to have your activity act as if upon rotating that you can start right back up, where you left off, there is a method called onRetainNonConfigurationInstance(). It's basically the method that stashes objects which can't be parceled like in saveInstanceState()
So the idea being:
public void onCreate(Bundle a) {
...
AsyncTask myTask = getNonConfigurationInstance();
if (myTask == null) {
myTask = new AsyncTask();
myTask.execute();
}
...
}
public Object onRetainNonConfigurationInstance() {
return myTask;
}
This will keep the async task running, and when you get your onCreate called after the rotation you just pick it back up and do what needs to be done.
One thing to be conscious of is the progressView. It will have to be destroyed and reinitialized to the new state. Also the overall dismissing of it and showing it in the first place should be done outside the AsyncTask. But nothing is to say that the AsyncTask can't call some callback that you always set in your onCreate() so that it will notify to tell to update the UI or play a sound of completion, etc.
You could also decide to handle the configuration changes on your own through the use of the android:configChanges in your manifest.
You then implement the onConfigurationChanged method and perform any actions inside.
See the developer doc.
When a configuration change occurs at
runtime, the activity is shut down and
restarted by default, but declaring a
configuration with this attribute will
prevent the activity from being
restarted. Instead, the activity
remains running and its
onConfigurationChanged() method is
called.