As my app (game) is getting larger and larger, I've started to encounter a problem.
I have a menu activity with a 'start game' button - when the user presses this button, it starts the main game activity - now in this activity, I'm creating bitmaps etc in the constructor but there are so many that now when the activity starts, there is a slight delay - about 2 seconds - before the game actually starts.
I'm clearly doing something wrong - please could someone advise how to get around this so the delay (which clearly, has to happen) - isn't noticed by the user.
Load the ones you need immediately right away. Load the rest on a background thread (probably an AsyncTask). If you need one before it may be loaded, either pause or put up a loading screen as needed.
You could start loading the bitmaps in the background of your menu activity, or even when your app is created using a background thread or AsyncTask. You'll still need a loading screen of some sort in case the user navigates to the main game activity before you're done loading all of the bitmaps though.
You can also kick off an IntentService to load the bitmap. When the bitmap is loaded the IntentService can send a broadcast using LocalBroadcastManager. Then each component that cares about a result can register a BroadcastReceiver with LocalBroadcastManager.
Related
I'm working with an app that grabs a decent amount of data upon start each time since I need to immediately know things like location and weather fcst in the area.
In my mind I see a loading animation that smoothly moves around for 3 to 7 seconds while everything runs so there isn't just a blank screen or a static title image.
BUT:: I'm running into issues with getting animations or images to load before all of the data is searched for. And I only want the animation to run as long as data is loading. So I have the application switch to a new activity as soon as everything is loaded.
Is there a way to for the animation to run before things are done or do I need to somehow set everything up as an async task. And then how do I pass the async task to the next activity?
So I found an answer to my own question after reading some books. In short, the loading screen that i was looking for uses a splash screen with asynchronous tasks. Either AsyncTask directly or you can implement a service solution.
Extra: I noticed that if you run an async task which starts a GoogleAPIClient, onConnected executes on a pool thread or something, point being you can do UI work on the main thread again without wrapping back to AsyncTask.
I've got the following problem. In my app I'm loading data in an AsyncTask. The problem is, when the user now clicks on the icon to open the Navigation Drawer and opens up another fragment the app crashes. When the AsyncTask is finished the app doesn't crash. The problem that is encountering is, that when I switch the fragment (The fragments are always the same, just with another content dependent on the NavigationDrawer Item click) the app crashes.
I guess the problem is, that the async task isn't finished, I'm calling the same fragment again want to display different data.
So what would be my approach to handle this? Use for every different view a different fragment? I thought using the same fragment every time is much easier, since it's just displaying different data but the structure, layout etc. is all the same. Just the data that it gets is different.
I also thought about somehow "blocking" the user from doing any other actions while the asynctask but still show him that the app is processing. But that would be not the definition of an AsyncTask.
How would you approach it? Use different fragments for every different display? Or how? Block somehow? If a user clicks on an item of the navigation drawer the asynctask needs to stop all its actions (if some are done) and then restart doing all the actions. Is there a way to do it?
Please note that the fragment where the async is executed and the activity where the fragments are called are in two different files
You can either block the screen with a loading screen (not that good UX wise...) or you could cancel the asynctask when you change the fragment, in the destroy or detach method.
You didnt show the errors, but I would guess that the app crashes because you are trying to acess something in the asynctask onPostExecute method and it is no longer available...
I guess that it crashes because your AsyncTask is sending data to a class instance that doens't exist.You should change the Class that receives callbacks from asynctask. Anyway i can't give you a better answer till i will see your real code of AsyncTask ( at least onPostExecute() and onProgressUpdate())
use intent service to do that ask task means call ask task in a intent service that one is capable to handle background task without hang UI
I want to build a "smart downloader" that can download images in background (using AsyncTask).
There are two Activity, A and B. In activity A, I can choose the image list I want to view, (first download if not have been download once). Then enter activity B, here I launch a asynctask to download the image in background and in the UI thread, show the image to the user.
there are some large list that may take minutes to finish downloading. One tricky problem is when the asynctask is still downloading the list, the user may exit activity B (come back to activity A. (I know the asyntask will still continue working even if activity B is destroyed).
But if at this time user choose another list to view (then enter activity B). I want to stop the previous task for a while, began to downloading the new list first, and then the old list.
My thoughts to do that is retrieve the previous asynctask and modify the downloading order. But I don't know how to retrieve the asynctask, I have search some questions about recreate asynctask, but they are all about after re-configuration (like rotate the screen). is there a way to retrieve the background working asynctask, after i destroy the activity and recreate it.
Thanks!
Once you destroy an Activity, the AsyncTask is gone. For this reason, AsyncTasks are not the optimum solution if you want to avoid running the background operation from scratch.
I think you should structure your app to download images using an IntentService. In activity A, choose the image list. Once it's chosen, fire off an IntentService to download the images. Once the IntentService is done, it can notify the user that the operation is complete or send a local broadcast message back to the activity. In either case, even if the user has navigated away from the activity, the work hasn't disappeared. If the activity was destroyed, you can figure out if the download is done, and if so, display the images. If it's not done, you can put up an activity indicator.
I've got an app that uses ListActivity to give users a list of actions. When they click one I use an Intent to launch a separate activity.
My problem is that the actions that the app performs take about 20 seconds to finish, and since I don't want the user to receive that nasty ANR dialog, I tried to use AsyncTask to present them with a loading screen in the mean time. I tried using setContentView(R.layout.loading); on onPreExecute(), but it throws a NullPointerException which as far as I have figured out is due to the fact that loading.xml is not "a ListView whose ID is android.R.id.list".
So what can I do now? How can I show that loading screen? Is there a way around this pretty annoying situation? Any help would be greatly appreciated. Thanks!
I am not sure exactly what your use case is; you have a list of items that are populated immediately, and upon selecting one an action is taken? The action that is taken is to launch another Activity which performs background processing?
Or does it take that long to populate the list of actions?
If the former, you can use an AsyncTask for the long-running activity instead of an Intent to launch another Activity: in the callback you get for the click on the item in question, you would create the AsyncTask, and in doInBackground you would perform the long-running activity, with onPostExecute refreshing or manipulating your list as necessary.
Another thing to consider is using a dialog box to show a loading screen, if the loading is required to happen before you launch a new Activity.
If you can further describe your use case, I can help you more.
It's not the loading screen you need to have on the AsyncTask, it's that 20-second Activity initialization. I would look for a way to do all the setup in a background thread in a Service while the user is free to merrily bop around in other Activities. I'd try hard to find a way not to just stall the user for 20 seconds. Maybe take them to the target Activity and show them data cached from their last visit until the new set is ready.
Fire up and display your loading dialogs in your onCreate() of the Activity being called, then call Dialog.dismiss() in your AsyncTask's onPostExecute().
I have 2 activities :
- activity A is gathering data from internet (it takes some time)
- activity B is building UI elements based on the data previously received (it takes some time too)
When activity A start downloading, the app enter a loading phase. When it's complete, activity B starts, so I have a transition between the views of A & B. Then B requires also a loading phase.
I have loading - transition - loading - result which doesn't look nice at all.
I would like to have loading - transition - result where the loadings of both activities are grouped.
So my question is : is there a way to start the activity but to delay the transition ?
I don't think you are going the right way about this. I would suggest just having one activity with a loader. Then use something like AsyncTask to load the data in a different thread. Update the UI as the data gets loaded and then when everything is done remove the loader. You should use multiple threads to do work that takes time because otherwise your UI will freeze. Looking at what you said above, I don't see why you would need two activities.
You can use an ActivityGroup: http://developer.android.com/reference/android/app/ActivityGroup.html
This would allow you to achieve what you want. I don't think it's possible without it - (if you really need to wait until all UI elements representing the data are drawn. Otherwise I would suggest to follow Amir's advice below).
You put both activities into the ActivityGroup, but hide B at the beginning (visibility=gone). Then you can swap the visibility / do the transition once the data is loaded and the UI for B is built.
I'm curious though what kind of layout/UI you have that takes so long to build, if the data has already been preloaded in A.