I have built an Android app that allows a user to create new levels for a game I am making. The level maker app allows the user to save new levels and preview all levels they have saved. When the user saves a level, my app generates a JSONObject that represents that level, then writes the JSONObject.soString() value to a local file (either a Shared Preferences file or a plain old .txt file - I don't know which is better yet). When the user wants to preview existing levels, the app reads in all the JSON Strings from my levels file, converts each JSON to a Bitmap (JSON -> ViewGroup -> Bitmap), then displays all the Bitmaps in a ListView.
Right now I am using 2 AsyncTasks: one for writing and one for reading. I don't know if I could potentially be spawning 5-10 new Threads per minute, though (one for each time the user saves a new level), and I don't know if that would be a bad thing as far as system resources goes.
Here's my question: because I may need to write to my levels file 5-10 times per minute, is it better to start a new AsyncTask each time the user saves a new level, or should I just create one background thread and execute Runnables on it each time the user saves or previews levels?
AsyncTask is controlled internally by a shared (static) ThreadPoolExecutor and a LinkedBlockingQueue. There are such parameters like core pool size and maximum pool size. Since Android 1.6, core pool size is 5, and the maximum pool size is 128. Queue size is 10 tasks.
So, maximum quantity of parallel AsyncTasks is 5, others will be queued. If your save operation is relatively slow, you may encounter situation when AsyncTask got killed by OS and nothing saved. If you need long-running save operation, it is better to use service.
For me, I prefer using background service with my own ThreadPoolExecutor - this gives me some extra control like cancelling tasks. If you don't want to write extra code, you may use IntentService - it also uses Executor and queues your tasks by itself.
Related
I am trying to optimize a complex data updater and parser for my Android app. The server provides three interface functions. The parser requires the data from all those three functions.
When the download of the data is finished, the parser can start. It consists of many different independent tasks which can be parallelized.
I was thinking of using Futures or FutureTasks for processing the data.
So basically, this is the procedure:
create Task-1, Task-2, Task-3 for downloading the data
wait for the downloads to be finished
create Task-1,..., Task-N for parsing the data
wait for the parser to be finished
call a callback to signal that process is done.
My first question: is it possible to create Futures with asynchronous functions, which use callbacks to return the data (network framework)?
Second question: are there any drawbacks in using Futures or FutureTasks respectively in this scenario or are there any better solutions to achieve that?
Thank you.
Basically you are Trying to achieve the following.
Step 1 - User from UI starts 1,2,... n download tasks.
Step 2 - Once each of the task is completed, new thread should be started to process it.
Step 3 - Once all n Tasks are completed, UI should be updated ... may be with a success dialog.
This can be achieved easily by using Async Task. I am going to tell you the approach and not the code sample.
Things to note about Async Task
Before 1.6, Async Task handles all background operations with a single additional thread.
After 1.6 till 3.0 .. it was changed, so that a pool of thread had begun to be used. And operations could be processed simultaneously.
Since Honeycomb default behavior is switched back to use of a single worker thread (one by one processing).
How to implement your requirement
For your requirement, you can use the method (executeOnExecutor) to run simultaneous tasks (1 till n tasks) if you wish (there two different standard executors: SERIAL_EXECUTOR and THREAD_POOL_EXECUTOR).
The way how tasks are enqueued also depends on what executor you use. In case of a parallel one you are restricted with a limit of 10 (new LinkedBlockingQueue(10)). In case of a serial one you are not limited (new ArrayDeque()).
So the way your tasks are processed depends on how you run them and what SDK version you run them on. As for thread limits, we are not guaranteed with any, yet looking at the ICS source code we can say that number of threads in the pool can vary in range 5..128.
When you start too many tasks (like 100s or more) with default execute method serial executor is used. Since tasks that cannot be processed immediately are enqueued you get OutOfMemoryError (thousands of tasks are added to the array backed queue).
Exact number of tasks you can start at once depends on the memory class of the device you are running on and, again, on executor you use.
So by following this approach, once all the tasks are completed, you can use a handler to update the UI.
Hope this helps.
I'm currently working on an Android application that requires reading from call history and text history. And for further analysis, I've extracted these the huge amount of entries from the corresponding content provider, created and inserted all of them to a SQLite database.
But the problem I've encountered is when this is running on a phone that has been used for years (meaning there's an enormous amount of data generated from calls and texts), the retrieval process and database building process takes too much time and may even cause the app to crash. Even if i tried to put these process in a AsyncTask, the problem still exists. So my question is:
Am i doing it in a good way to just put any time consuming operations away from Main UI, OR What's a better way, if any, to handle very very large amount of data in Android?
Use pagination logic. Fetch only the most recent and relevant data and load older data if the user requests it.
Call history on most android phones is limited to 500 entries CallLog.Calls, while SMS provider has not such limits, you can query the count of the tables and limit your queries to 50 at a time and pass it to a separate thread for processing. Also make sure you run this in a background service with low priority so as to not disturb any other operations ongoing in the device.
I am working on an image processing Android application. Suppose you have a C++ singleton object that provides some time-consuming functions and allocates its own memory. Furhtermore, the C++ library will provide some other functions that will do some time-consuming work as well. This functions will be called by the singleton object. They can allocate their own temporary memory (that will be freed on function termination) and need to exchange data with the singleton object. The workflow is the following:
the native C++ library is loaded, the singleton object created (it will allocate memory and load data from the asset directory).
the user, using the application interface, select an image and loads it
the image is passed to the singleton object that will computes some informations
the user can request a particular image processing algorithm, the singleton object is asked to call the corresponing function
repeat from 4 or go to 2 if the user load another image (the singleton object will be resetted (the memory allocated on step 1 is retained until the application is tereminated)).
Step 2 and 3 are the most time consuming part of the app. I would like the user to be able to stop the current processing if too much time is passed and the application to remain responsive during the time consuming processing algorithms. The most simple way to do this app is to call the native functions and wait the, but this will probably block the UI. Another way is to design those functions to check a flag every N processed pixels to know if the function must stop (this would allow me to free memory when it happens). A third option could be to use java threads, but how?
You will have to run the time consuming task off the UI thread. You could do this with a native thread, but it would be simpler to call the native function from a background thread in java - there are several ways you can do that, such as an async task, etc which you can read about.
When you start the time consuming operation, you'll want the UI to display some sort of busy indicator to the user. The UI thread will have to remain responsive (ie, the user can 'back' or 'home') but you can disable most of your other controls if you wish.
Your native operation in the background thread would, as you suggested, periodically check a stop request flag. You will probably find it easiest to make that a native flag and set it with another (brief) native function called from the UI thread; there's the option of making it a java flag and calling java from C to check it, but that seems more complicated.
If your processing is going to be especially lengthy, arguably you should do the work not only in the background, but in the context of an Android service rather than that of an activity. To a first approximation, native code will not care about the difference, however there are potential implications for what happens if the activity goes to the background during processing - if the work is being done in a service (or more specifically, if the process contains a service which is active), Android will try to let it keep running if possible. In contrast, if the process only has an activity which is now not active because something else is in the foreground, Android is more likely to kill it or throttle its available CPU. Ultimately, whatever you do your native code will need to deal with the possibility of its process being killed before the work is done - ie, you have to be able to recover from such a state when a new process is created as the user returns your activity to the foreground. Having your flag also able to notify the native code of an onDestroy() call as an alert to save its work could be a help, but it will still need to be able to recover (at least cleanly re-do) from being killed without the courtesy of that notification.
I'm new to Android programming and I have a threading issue.
I'm basically populating a GridView with images from 50 or so URLs, but those URLs will not be known until I retrieve a JSON object from an already known URL. I know that I have to fire off a bunch of threads for each URL download (using the AsyncTask class).
How can I effectively queue these threads so that the JSON thread is executed and finished first, so I can use data retrieved from that thread when I fire off those 50 image threads immediately after?
Do not start 50 threads. Use a single thread. While this should be separate from the UI thread for responsiveness, there is no need to spawn multiple threads, and certainly not one thread per URL.ce
Simply make your JSON network call, then parse the response, then (in the same thread) loop through the URLs requesting each one, and decoding the result into a Bitmap. You'd them add them within some model object to the Adapter for your GridView, which would automatically trigger the GridView to update on the UI thread.
There are better practices here, such as lazy loading, caching, and displaying a placeholder image while images are loading, but the exact implementation becomes too complex to describe here. Search for WeakReferenceMap and LruCache to find examples of the best practices for dynamic image loading into an AdapterView.
Well, you could just run the first fetch and when this is done, fire the 50 threads from this main thread. As Android 3.0 and later will kill your app when you do network communication from the UI thread, an AsyncTask could be a way for to fetch the JSON. When this returns it could fire the other threads.
One thing you should still consider is that Android is, as powerful as it is, still a device with limited capabilities. 50 Threads may use more resources that the target handset has and thus your app may be killed by the system (e.g. because of OOME). So wile on a desktop 50 threads don't sound much, they are much on a phone.
Also IIrc, there is a limit in the http spec, that one may only have 4 (?) simultaneous connections to one remote server. So consider queuing up the image loading requests and fetching them one after the other.
Suppose I have an array of shorts of length 1,000,000 and that I need this to be generated or loaded into RAM (ideally within a few seconds) when my app starts and before I get an activity thread timeout.
I'll then have quick access to its entries during runtime.
How would you go about loading this to memory from file? Loading from txt file? From an SQLite file (with two integer columns in a single table, one for index and the other for value)?
Is it possible for an activity to request a longer idle time before it's deemed to have timed out?
The solution to your problem would be to spawn a thread to do the file reading. This is going to be a high level overview so you can track down the relevant items. It will address item 2 first, then item 1.
First, you need to get your long running processing off the UI thread. The 'idle' time responsiveness issue (application not responding) is because you are tying up the UI thread which is needed to do other actions. The thread cannot be reading a file and drawing the screen at the same time (at least not well).
I've found the easiest way to do this is using the Java ExecutorServices. What you want to do is package the logic for reading the file or database into a java Runnable or Callable and then run that using an ExecutorService. The executor will take care of starting a thread and reclaiming those resource when they are no longer in use.
One key issue to be aware of is that, once you create another thread, you need to be careful when updating the UI. Because ui objects are not thread safe, you can only update the ui from the UI thread (common sense, right?). If you are in an activity, you can do this by calling runOnUiThread() or you can create your own Handler in one of the ACtivity methods called by the UI thread in the first place.
Sam Dufel said:
Hmm... You could really pack that down if you could come with a format to replace all the dummy entries with just a count. Eg, 10,000 zeros get replaced by a pair of flag bytes followed by 10,000
Additionally, you may see increased speed by spawning multiple read threads. If you could break the file up into two files which would allow two threads to execute simultaneously you could see a significant speed up (depending on what else you need to do to the data). A sort of divide an conquer for loading up your data from file. A cursory google search should give you information on how to load shorts from a file. You should most definitely consider using a binary format given your specifications.