I am starting an activity with a Serializeable extra. This extra contains a List of a custom object holding a bunch of types, mostly Strings. I read in the data from the assets folder of my project, and parse it with GSON(the data is JSON). This file is ~108KB in size.
For the life of my application, all data is being passed around as intent extras. This is very convenient as i don't have to worry about re-loading the data from the assets folder again, app shutdown recovery is all taken care of, and i don't need to manage an SQLite database(versioning, queries, etc).
Problem:
I find that passing these extras around can become quite slow(starting an activity with ALL the data takes maybe 1.5 seconds or more). I can't seem to show any "loading" dialog either, as it seems to be a blocking call to start an activity and attach extras.
Question(s):
Should I avoid passing these extras around like I have described? Is the best option using an SQLite database to interact with this data? What suggestions do you have to avoid a lot of the fuss of SQLite databases/global static variables for accessing my application's data?
Slapping my JSON data into data model classes and passing them as intent extras is easy and nice(seemingly), and i don't want to give it up!
I had the same problem and followed the solution you already depicted. I used an SQLite DB to store the information, then passed only unique ids as intent extra and displayed a "loading..." progress dialog on the called activity while I accessed the DB.
Prolly using SQLite is the way to go.
Why don't you load the data to the Application class, onCreate of the Application class, and then access from every activity there?
Related
I have created an app with two activities as the activities with two separate lists.
Let's call them: Activity1 and Activity2.
With the home screen of the app called the MainActivity.
As soon as the app is launched, the MainActivity is created and notifications appear in the notification bar based on the list item's statuses.
I've had a look at the lifecycle of Android but I can't understand and figure out where to load the lists and when to save the lists. Also, what is the best way to save large list data in Android to internal storage? Json? Csv? File type basically? :)
For example, would I load both lists when the MainActivity is first created, onCreate(). And then save the list of(for example) Activity1 when the user navigates away from Activity1, onPause()?
To reiterate, this is what I need help on:
I've had a look at the lifecycle of Android but I can't understand and figure out where to load the lists and when to save the lists. Also, what is the best way to save large list data in Android to internal storage? Json? Csv? File type basically? :)
Thank you for any help! :)
As you may have already known, onCreate will be call when Activity is instantiated, so all initialization, including populating the Activity with list data loaded from a file or shared preference. In terms of when to save the list data, it totally depends on how you want to modify the data, as data only needs to be saved when it's changed from its original state.
Of course, you can also load data every time onResume is called, and save data again when onPause is called, just to make sure data is synchronized if you have multiple applications modifying the same list data.
There are many different ways to save list data. I would recommend to use SharedPrefernce as it will save you some troubles. Please read this for how to save ArrayList to SharedPreference. If you don't like this, you can always save the data to a file with some standard format (JSON, XML, etc.) and parse the data when reading from and writing to the file.
A good entry point to load a data is in "OnResume". It is called every time your activity will be presented to the user.
Saving your data can be placed in "OnPause".
"OnCreate" is only called when the activity will be created, which will happen only once for your MainActivity.
I'm new to Android development and was unable to find how to pass values to an activity that is not the next screen that the user will see. If I have activities in this order: 1>2>3 connected by buttons, how do I pass a value from 1 to 3? I'm only familiar with using intents on button clicks, which would require me to pass the value to screen 2 and then to screen 3.
Thanks
There are several ways to do that:
1) From Activity1 you pass data though Intent. In Activity2 you retrieve data and pass it within new Intent to Acitivity3.
2) Save data in SharedPreferences in Activity1 and retrieve them in Activity3.
3) Save data in SQLite database which is default for Android. This is a good option if you need to save/query data not once, but many times.
4) Save in Google Cloud or use other services.
You can see here a full bunch of store options in Android. Without performing those actions, storing/retrieving data though the Intent is the only one way.
Note: Make a static variables is such a bad practice, unless it is just constant values or other utilities.
If the chain pass becomes too complicated then you should persist it. My suggestion is using Preferences to save the value. Later you do an existence check in the retrieving Activity, load it, and if needed clear it. This is the method commonly used when storing app Settings values.
If your values become more complicated in structure and more numerous then you'd need to consider database.
I have a ListView that is displaying data from a large dataset. The data is retrieved from the web and put into a List<Data> (i.e. in memory) by a background task. (Think email inbox with polling updates.)
My problem is how to pass that data to the ListFragment/ListView/ListAdapter to display.
This List isn't permanent (so not in a Content Provider) but lives longer than activity (it's updated in the background when the activity isn't alive yet).
The only options appears to be:
Pass it via an Intent/Bundle. This requires serialization on some level which will be very expensive for my long list, especially as each time the List updated in the background, I have to set a new List which means the entire list gets re-serialized.
Create a Singleton that provides the list from anywhere in the program, and access SingletonListProvider.getInstance().getList() from my ListAdaptor. I don't like singletons and I'm worried about concurrency.
Use a ContentProvider. Seems overkill for a simple List<> that currently lives in memory
Are there any other options?
It seems I have little control over how the Activity (ListFragment in this case) is created so I can't just pass the List as a constructor parameter.
Best way is to use Database, especially if your data-structure large.
By the way, you shouldn't create ContentProvider enough to extend SQLiteOpenHelper.
http://www.vogella.com/articles/AndroidSQLite/article.html#sqliteoverview_sqliteopenhelper
Hello fellow developers,
I am trying to achieve something in Android and I would like some advise on the best practice.
I have created an Activity which can start and stop a Service which collects data.
Instead of simply starting and stopping the Service, the Activity should also display the data collected by the Service.
Here in lies the problem. The data could be quite large so I would like to avoid Serializing and sending it via an Intent. Is it possible to simply get a reference to the data stored in the Service from the Activity?
Simple Example
1) Activity starts
2) Activity starts Service to collect data
3) Activity exists
4) 24 hours pass
5) Activity starts
6) Activity wants to display data collected by Service, but data is quite large.
My question again is simply this. Can the Activity get a reference to the data stored in Service or does the data have to be Serialized and sent from the Service to the Activity using an Intent?
Kind regards,
Cathal
Research android.app.Application class. Essentially you can use this for global state.
http://developer.android.com/reference/android/app/Application.html
Also, any long term data should be stored to a local database. I would try to limit the SELECT to certain number of records to reduce memory footprint.
I've heard that the Application class should not be used in this way necessarily (via Google Team). Instead you could make a separate Singleton class (For example call it "MyData") that holds a public static reference to a let's say ArrayList (For example called "list_data").
So when he activity starts it will call
MyData.list_data = new ArrayList<MyDataObj>();
Then in your Service you can add all of your data objects to this static arraylist like so:
MyData.list_data.add(new MyDataObj());
This allows you to work off of the same ArrayList without passing it around using Intents and etc. Although I would suggest doing some null checking whenevr
I have a ListView with a custom ArrayAdapter, that shows orders from an ArrayList. These orders are supposed to be synced with my server. There I have an API, which I am requesting for new orders, and if there are any, I get an XML of the order back. What is the best approach to dynamically update the listView? I do not want to use SQLite to store the orders, because only last ten are supposed to be displayed. With a ContentProvider I am not able to store my custom Order object. And if I wrap the ArrayList into a singleton class and use it in the service as well as in the Activity class for the ArrayAdapter, the ListView is not dynamically updated (probably, because the arrayAdapter makes a copy of the arraylist?). Thank you very much.
Filip
use Intent or Bundle
i'm no sure what you mean regarding the ArrayAdapter not being updated, but i can give you a solution we used in my company.
I have a DataMaanger which is a bridge between the Activities and the Networking or SQLite.
The dataMaanger keeps it's data in memory so it's not in DB or on disk. the disadvantage of it is if your app gets killed for lack of memory and reconstructs itself, the dataManager will be empty, which leaves you with two options, either on every Activitie's death or you main task's activities death you serialize your DataManager's data, or if you are not dependant on any previous data, just make arequest again and update the data manager.
I use broadcasts to notify my activities.
To get an access to the DataManager i don't use a sigletone. i use the Application object, you can extend it and in the Manifest.xml give it's name in the tag, then it will be used instead of the regualr Application object.
You can access it later by using getApplication() method in Activity class.