Lectori salutem,
I'd like to implement a search in my application, my main data stucture, a ListOf(custom class) is in my main activity. Which is a json-ed object with over 2500 objects. The json file gets loaded/parsed on the startup of my application, this takes about 30 seconds. So passing the data in a .putextra is really not an option. The search dialog would take 30 seconds to even start searching, not to mention you'd have twice the memory usage.
So question is, what are my options here? Is there a way of passing the search query to my mail intent, and handle it there, so I can address the existing data structure?
It sounds like you would be best off using a SQLite database. You can even distribute a pre-populated database with your application to minimize load time.
You can get started here: http://developer.android.com/guide/topics/data/data-storage.html#db
Why not try to keep the information in a singleton object? Or in your App class for example? Any of these should give you access to the object anywhere in the app.
You should check if the data being copied into new object, or the reference of it being past. I'm pretty sure only the reference will be sent, and you don't have to wait for the object copied into new one. Therefore, stick with the putExtra, if you don't wan't to create static reference, who is the evil demon that summons memory leaks :)
Related
I am currently facing a problem with persisting object state in an android app.
I have some kind of multi level master-detail flow.
For example, I have a list of Clients. Each Client has multiple Orders and each Order has multiple articles.
Until now I did the following:
When you click a Client in the MasterActivity I write the Client into the Bundle and open the DetailActivity.
In the DetailActivity I read the Client from the Bundle and display it.
This worked more or less fine most times, however it now happens, that an object is too big to be serialized (for example a Client with a lot of Orders).
Therefore I wanted to serialize only the ID of the Client and load it from the database inside the DetailActivity. Usually this approach works fine but I have one situation where it does not work:
The Articles are only saved, when you save the Order (their Master). So if you create a new Article for an Order and you don't save the Order, the Article isn't saved too.
That means, that I always need to have the full object, reloading it
from the database inside the DetailActivity means, that I loose all the unsaved changes. However, persisting it, using the Bundles could exceed the limit (500kB to 1MB).
So my question is, what is the preferred way to persist such data?
A nicer way is to create your own singleton class which points to data you want to transfer between activities.
I suggest DataManager singleton activity which has Article articleToPass
Make the setter set the articleToPass to point to what ever you want.
and the getter or reader, will read fetch the article and nullify the articleToPass.
manage your app data using this DataManager singleton (This dataManager singleton can be initialized either in the extending Application class or MainActivity).
Incase you must persist the object when app is destroyed and loading back:
Create from Article object a DB entry which contains all data you need (I see no reason why saving data you don't need here)
Dump all data to some file (Using Shared Prefs, key and values)
When entering the Details screen you want make a query to a sever of yours requesting all data you need by ID or such.
Convert all object you need to JSON (simply using GSON), and dump the JSON to a file, and load it when you need.
I think the resolutions above are enough :) hope i helped
You can subclass your own MyApp class from Application, specifying it in your manifest. This class is a singleton and is available all the time the android application is running like this (MyApp)getApplication().
So, in a field of this class you may keep some temporary data you need to keep between activities.
You have to check if this field is not null though because the OS can terminate your app anytime. In this case you will have to reload the data. You can keep some index of what data to be reloaded somewhere in the SharedPreferences.
I'm using IntentServices to call a restful service and then turn over the result to a receiver. The back-end requires a user id and authentication token, which I stored in a singleton class. I've run into issues with this singleton being cleaned up when the process is terminated, and its data isn't around when Android tries to restart my activities. User preferences seem like a great place to start this kind of data, but those require a reference to your context.
Where can I put this data so it can be accessed outside of the view? I realize I could just pass it with every single Intent that triggers my IntentService, but am hoping there's a better way.
Thanks!
Service is a ContextWrapper which is a Context so you can use the keyword this when getting an instance of your shared prefs.
For lightweight data such as a few strings etc, SharedPreferences is fine. Just pass any context, every component has one or is one itself. Or pass the application context. Lack of context shouldn't be an issue. Pass it along into your singleton as a parameter.
Using a database, or inventing a proprietary storage mechanism using a file, or creating a content provider, all seem overkill to me.
If you don't want to pass it all the time (which is not that bad), and you still want to stay in the Android framework philosophy, create a ContentProvider for this task.
Or you can go full classical and save them in some file. Or in a sqlite database (Android offers easy support for this).
I'm new to Android development and have written a small app that calls a web service and hydrates a relatively simple object (think: auction listing or something of that magnitude). Right now, when the phone rotates and the view is reloaded the web service is re-called, the object is re-hydrated and the listing re-displayed. This seems very wasteful. What is the best practice when storing data via onSaveInstanceState? Is it considered OK to store the object itself, or is it best practice to store the ID and go through the whole process of loading it fresh each time. Are there any other rules of thumb or gotchas to be considered here?
Thank you
JP
Even re-creating information form a database is usually considered too much effort for the Android config change scenario.
What you want to use is to create a class holding references to objects which you want to survive the config change, and have your Activity have a reference to that. Also, you will return that in the onRetainNonConfigurationInstance() callback. In onCreate(), you call getLastNonConfigurationInstance() to see whether this is a re-creation due to a configuration change. This call will return your object with all the data you need.
Since you are calling a web-service to populate your list, I guess you should store your list's data (calling web-services consumes time and may fail if your user doesn't have a steady connection). Which you can do in different ways (a database, for instance). This approach would also help you if the user restarts your app, since he won't have to wait until the web-service responds.
Also: re-consider your terminology when you ask a question. You don't usually see someone speaking of "hydration" of objects; it's more common to speak of populations and so on.
If you only want to avoid recalling service when orientation changes then you can add below in your Manifest in activity tag.
android:configChanges="navigation|orientation|keyboardHidden"
But as #DigCamara said, his approach is best and even useful for other scenarios like restarting.
Cache your data as much as you can, every data connection has a "standard" cost in terms of time, resources, and ultimately battery life.
Try to group your requests and make them all in once and cache the responses as long as you can.
Good read about network on android developers
Of late I have been into an issue which has been really difficult to sort out.
I have an Activity A which has a view pager with fragments. I am loading data from server and feeding into the views. The data received from server is stored in a singleton class which can be accessed across the application. Now user moves to another activiy B which uses the server data through singleton class.
Now when user presses home and launches variety of application, my app gets killed in background. When I relaunch the application, OS try to load activity B again with its saved state(I am not doing anything in onSaveInstance), but the data in singleton class is already lost and app crashes. The thing is I cannot get the server data again in this activity. Should I save the entire data in onSaveInstance of this activity? Is it not encouraged to use singleton class to store all your data?
What is the ideal way to handle situation like this?Any help is appreciated.
How sensitive is the data? In Android is is not recommended to use a skeleton to move your data around(Passing it through intent? Static(please say no)). Ether way was commented you should probably store the data to main memory. Android provides a few options besides actually writing it to a file. Depending on how much data and its structure there are a few options.
ContentProvider & ContentResolver, Basic Overview. I would not recommend this unless you plan on making the data accessible to other applications.
SQLite. Good if you have preexisting sql knowledge or large amounts of data where a relation db is needed.
SharedPreferences. As its name implies is generally used for storing user presence data, but it can also be used to store any data. I would not recommended it where there is a lot or complex data is needed to be stored.
File. Good old java file classes, no explanation needed.
With our data I would recommend creating a DataStore managing class which handles the io to any of the above methods, so when referencing the data you simply pull from that class.
To avoid such situations, you should relate to these:
App crashes when restoring from background after a long time
http://www.developerphil.com/dont-store-data-in-the-application-object/
I have a database from where i need to extract quite a lot of data.
Now i get that data when required, i.e. I have made a class that handles database interactions and whenever an activity requires data it will call that class for the data. So at a time an Activity only has the bare minimum amount of data in memory (i.e. the data that it is using). But everytime i change an activity i have to perform database access to fetch data for the new activity.
Method 2
As opposed to this i have this other alternative, in which i make an application object and then perform database access in the beginning and then store all the data that i would require (in all the activities) in the application object. Whenever i need the data, i refer to the application object. The downside of this that i will be holding too much extra data that i am not using at a given instant.
Which of the above 2 approaches is better?
Thank you in advance.
It depends on your requirements and their priorities. If the time required for solution 2 is too long for you to accept then optimize (e.g. by using method 2, but in general I would advise against storing potentially all of your database in memory ... assuming the amount of memory will suffice).
Did you try solution 1. If the problem is only to read the data from database, it should not take too long to load the data for one activity. If complex calculations are involved you might be pressed to optimize. But don't optimize just in case!
I prefer the first approach because making a call to database is not costly until and unless it is being accessed by multiple applications.