In my application I want to pass an ArrayList of Parcelable objects (or a Parcelable[]) between two activities. On the first activity i call a restservice to get the json data, after that I use gson to get the List of Parcelable object and then i send the list to the second activity using putParcelableArrayListExtra(...). All works fine until the size of the list is about 1000, but over this size I get an ANR and application won't resume even if I wait for some minutes.
Is there a solution for this issue maintaining this approach? Is it due to a size limit for object put to an Intent?
I know I could pass the Json String and then get the list on the second activity, but I prefer to make first this kind of operations.
First off, ensure that the source of your ANR is indeed the large parcelable object, and not because you were performing a blocking operation (i.e. networking) on the main thread.
Now if the ANR issue really is due to these large objects, the right way to get this done is to deserialize the object and write it out to storage instead of passing it between activities. You're effectively doubling the amount of memory you incur by doing what you're doing.
Here are a few ways you can troubleshoot this:
StrictMode: StrictMode is most commonly used to catch accidental disk or network access on the application's main thread, where UI operations are received and animations take place. By keeping your application's main thread responsive, you also prevent ANR dialogs from being shown to users.
Traceview: Traceview is a graphical viewer to see logs created by an Android application. Via Traceview you can find errors in your application and measure its performance.
Memory Dump: You can create a memory snapshot and analyse it with the Eclipse Memory Analyzer.
Related
I'm wondering what the possible drawbacks are to running my queries on the main thread. At the moment I am loading data from a database using Room and am using this data to generate graphs for the user.
I have already tried putting my queries into separate threads using a runnable, but I am having issues with the application attempting to use data which has not yet been loaded due to the separate thread not finishing it's operation in time. I understand that I could implement some sort of listener or notification, but even then, the user will have to wait an undetermined amount of time before they may view the content because the data for the graphs that they are wanting to view never loads before the button that loads them is clicked.
I have done quite a bit of research and found that it is unadvisable to put the queries on the main thread because it could possibly hang up the thread for a long time and give a poor user experience. So, assuming that I will never exceed 1400 data members, should I worry about this? Are there any caveats that I have not been informed of?
Edit: I am testing the device on a Samsung SM-J106B which is running Android 6.0.1 and I have not noticed any impact on performance even when loading the max of 1400 data members.
DB queries could take long enough that they would cause the UI to skip frames causing a bad visual experience or worse trigger an app not responding exception.
I want to keep some objects in memory for operations in all the activities of my app and I also want to store those objects when the app closes. Which is the most efficient way of doing this ? Some possibilities that I can think of are:
1) Keeping local copies of objects in all the activities, serialize them and pass them through intent.
2) Keep local copies of objects in all the activities, serialize them and do file read and write on activity resume and pause respectively.
3) Make them static variables but I don't know when to do the file read/write operations in that case? This approach may leak memory.
4) Use Application object and define my objects as variables in that object. Since it has a definite life cycle like activity, I can do read/write accordingly.
I recommend your approach number 2. The reason is that there is no such thing as "the app closes". Android tries to keep it in memory until the memory is needed for other purposes. The process of your app is then simply killed, you don't get any callbacks called.
Singletons or the Application object can be used to cache the objects if you are careful to load and store them as necessary. However, this also means, that the memory used for them is only reclaimed if the app process terminates.
It depends on your data. All approaches are good in some cases.
I think you have 2 options:
keep data in sqlite. It is easier then files and faster. When activity starts request required data from db and show it. (use files if you really want)
create a singletone class to store data. Data will be loaded in memory and you can access it very fast. When data changes save it to sqlite or file. google "share data between activities"
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.
Lets say I have a Service S and Activity A. S downloads data for A (or handles some long running work, whatever), but A is not always present. I don't want S to hang around when it's job queue is empty: S should post the results of the finished works to some kind of a mailbox for A, so A can pull the messages when it comes back again.
Can this be achieved without using SQLite of file storage for the implementation of the mailbox? I'd prefer some faster mechanism, write operations tend to be quite slow on a device. I thought about using a simple static list inside the ApplicationContext, but afaik relying on the ApplicationContext results a risky/fragile solution.
Could anyone recommend a pattern for this problem?
Can this be achieved without using SQLite of file storage for the implementation of the mailbox?
Not reliably. Either it's a file, or it might be nuked before A comes back again. Remember that your process -- where all your static data members and the Application object reside -- does not live forever. Once S shuts down (which is a good thing, thanks!), Android is welcome to terminate the process, taking your "mailbox" with you if it is solely in RAM.
You could persist it to disk yet keep a singleton or something around as a cache, so if A returns quickly you can skip some of the I/O. Or, if it does not really matter much if the messages exist for A, you could keep them in RAM and simply shrug your shoulders if the process gets terminated first.
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.