When passing data around in Android (between Activities, for example), it seems that the primary accepted method is to use Bundles and Parcelables. The problem with this approach is that it serializes all the data, which is inefficient. I'm wondering - is there way to pass around references rather than the data itself for efficiency?
This may be less efficient (though should not be a big impact in most cases) but avoids keeping a references to object between activities. That helps to keep the architecture cleaner and with less prone to memory leaks.
You can use Application class, static helper classes, singletons or services in some cases to help you but make sure you know what you're doing with them.
I would say your best approach would be to make all data model objects parceleble, and make all activities extend a base class and use a wrapper or a helper method to pass your data model objects between activities.
I use this approach in all my applications and thus far it has been very helpful and minimizes the number of references used between activities and fragments.
There are a number of techniques you can employ, it all depends on what you are trying to achieve, for example you can use a singleton to keep a reference alive, or you may (although you really shouldn't) use a static reference. In the end it all comes down to what kind of data are you trying to pass around.
Remember that sometimes is better to rebuild an object, than it is to keep it alive until (if it ever happens) the garbage collector clears it.
I like to use the singleton design pattern.
http://en.wikipedia.org/wiki/Singleton_pattern
Related
It seems to me that if you have some state or data in android that you want to access from different activities (but don't want to persist) you need a singleton. Is this correct or are there other ways to design an application?
It is not that I have a problem with singletons. I am just wondering because this is so radically different from normal desktop application development.
What you said is definitely not correct and there are other ways to design an Android app.
Actually, for Android development, Singletons should be avoided or used sparingly and should not be used as the first or only solution. It should especially not be used to carelessly share data or state across Activities.
If you find your app requiring the use of Singletons for everything, then chances are... you're in need of a redesign for your app.
When using Singletons, there are actually a few things to keep in mind:
They typically live throughout the entire lifecycle of the App until they're closed by the system closing your app
Improperly created Singletons can easily leak memory
Improperly designed Singletons and excessive use of Singletons can use up a lot of unneeded memory
They're hard to use for testing
Overall, when using Singletons, you really need to think about if there's a sufficient need for that part of your app to be a Singleton.
For most situations, the answer is no. In the cases you mentioned, such as accessing state or data between Activities, it's a yes and no.
It's a yes because the need to access data might warrant the use of a Singleton. It's a no because the need to access the state of the app shouldn't.
Your use of the word 'state' is a quite unclear, but Activities should really be self-managed, since the state of an Activity shouldn't interfere with the state of another Activity. If it does, there are better ways to send that information to the Activity (such as using Intent extras) rather than creating a Singleton that is accessible for everything and existing for longer than it should.
There really is very few reasons to warrant a need for a Singleton.
In my experience, there are only two reasons that might allow for the use of a Singleton:
The real need for a single instance to exist
The Singleton is used very often and it's expensive to constantly create it, but there won't be any major side effects to keep it in memory.
For example, an SQLite Database is commonly used as a Singleton because a single synchronized instance of the database can help prevent more than one Activity or Service from reading/writing to the database. This helps prevent situations such as one object writing new data, while another object reads old data before the new data is written. Or the simple situation of two objects writing different data to the same field at the same time.
Additionally, an SQLite Database is also accessed very often by apps, so it doesn't make much sense to constantly open a database, fetch some data, close the database, open a database, write some data, close the database, and repeat.
I've seen developers use Singletons for a lot of situations, and most of them for really bad reasons.
The Good:
Databases
SharedPreferences (the app needs to access preferences way more often than normal)
Logging system
The Bad:
I saw a developer load up a large amount of Drawables and stored it in a Singleton upon starting his app... just so he could quickly use those drawables everywhere.
I saw some developers using Singletons to hold a list of created Activities, so they could access those Activities methods and views... (dead)
I've seen more bad stories, but I can't recall them now.
Also, keep in mind that even though I said things like Databases are a good idea to be used as a Singleton, I only meant it has the needs to warrant the use of a Singleton. A database doesn't need to be a singleton and there are other solutions available that might fit your app better.
So always think about whether there's a need for you to use a Singleton.
In your case, does the state/data you need to access by other Activities really need to stay alive for the duration of the app and can it be solved through solutions like: SharedPreferences, Intent extras, Callback Interfaces, Databases, static classes/fields/methods, and etc.
If you've thought out your app well and really think a Singleton will benefit your app best, then use it. Don't forget to use an Application Context instead of the Activity's Context, because the Singleton will definitely outlive your Activity and you don't want memory leak issues.
I'm a newbie to Android, however I'm not entirely new to Java. From what I can tell, the ArrayMap should be used over the HashMap due to less memory used/performance increase. I'm not entirely sure when I should use one over the other beyond that, however while attempting to send an ArrayMap over a Bundle/Intent, I noticed that I was unable to do so, yet I could with a HashMap.
So, I thought, instead of just succumbing to using HashMap, especially when it's not necessary to, I'll create my own Serializable ArrayMap, however I'm unsure as to how to go about it.
All I know is that I implement three methods, readObject, writeObject, and readObjectNoData, all which have a Stream as an argument. I'm assuming I have to go through each item in the ArrayMap, then write it to the output stream and read from the input stream to recreate the ArrayMap. What I want to know is... how I should go about doing so.
I'm sorry if there is a duplicate question, but I can't really find any at all. So I'll start off with an example to fend off any "YAGNI" (You Aren't Gonna Need It). For one of my projects, I maintained a nested ArrayMap of objects, with said objects being in the thousands, with nested key-values to reduce collision greatly. I can't go too far into it, as it was for a recent school project. I wanted to be able to preserve the data structure over the life cycle of the application, including onDestroy of MainActivity, without having to parse everything all over again.
My solution ended up being to create a constant (static final) ArrayMap and access that, which worked, but it feels like I'm going against the philosophy of Android Development. Also I'm assuming that when MainActivity is destroyed the constant is also destroyed as well, yet with a saved bundle, it will be preserved, which is what I want.
I'm getting off topic... anyway, I want to create a Serializable ArrayMap, but I have a lot of questions regarding it. For one, what would be the best format to represent the objects nested inside of an ArrayMap? JSON would be my guess, although I've never actually done anything with it before. Then, how do I get the information from the objects nested inside? Do I enforce that only certain objects that implement an interface I declare may be added to the map? Then HashMap doesn't have this requirement. Do I use reflection to obtain each field and value, but then isn't that super slow?
I cannot use any third-party libraries, however I would love to do this from scratch regardless as it feels like a good way to learn more, does anyone have any tips/ideas on how to properly approach this? Thank you in advance!
If I put my service and activity in the same package, Can I exchange data between them using some global variables? I want optimized performance, so, global variables idea seems good but is it possible? If not, what is the best option. If intents is the way to go, then would the performance be good enough? BTW, the service has a big hashMap (may be multiple). This map needs to be accessed by the activity?
Thanks,
Rahul.
I know if you have multiple activities in a project, it's possible to start up one activity with certain args.
http://getablogger.blogspot.com/2008/01/android-pass-data-to-activity.html
This might not be what you're looking for though.
Don't use global variables. They are volatile due to the activity lifecycle, so you run the risk of having them garbage collected.
You can accomplish what you want using ResultReceivers. Here's a nice tutorial:
http://lalit3686.blogspot.com.br/2012/06/how-to-update-activity-from-service.html
I'm looking to establish some "best practices" for Android, with regards to code reuse, ease of programming/understanding, performance and memory. So, you know, just good code all around.
It seems like a lot of the Android documentation and object design pushes you towards having lots of inner classes. AsyncTask likes to load data right into Views. Adaptors like to have access to the LayoutInflator.
From a code reuse viewpoint, it would be nice to build a few adaptors or AsyncTasks that solve your problems, and reuse them as needed. This means passing around your context though, which feels dirty and can lead to memory pitfalls if not done carefully. The other option is to bake all the AsyncTasks and Adaptors that an activity needs directly into the Activity. This makes it hard to reuse code, but you can see where things are going easily and since you're using the context directly it's harder to hold onto things forever.
I'm also concerned about writing code that will look familiar to programmers we might hire in the future.
What are the coding standards for Android? What is the "best design" for an application which needs to load nearly all of it's data from the web, have a UI that works on phones and tablets (with different activities in each), and be easy to work with and extend for years to come?
You should look at this on How to code in android.
And you can use inner class or make a seprate class according to your need. For example when all data is being loaded from web in json format i always use a seprate class with a static method which will return the jsonObject and then i can call this method anywhere in my app and extract data from it.
Also i use single inner class of asyncTask perfoming different task in my activity like seraching and loading data in listview, loading data on user prefrences change.and so on.
In custom adapter i always prefer different class for them. It'll really make easy to work with them.
Hope it will help.
I've asked this before, and this is the way I do it.
If I'm going to use the adapter many times, I place all of my adapters into a package called "com.myapp.adapters" As for the AsyncTask, I always use asynctasks as part of activities.
If you only have a short adapter that does a little bit of work in an activity, there's no need to create a separate class file for it. Just stick it into the activity.
In the past few months I have been focusing on cleaning up my code for readability purposes. As my app gets larger, it's critical that I have a handle on my variables, classes, methods, etc.
This being said, I often question my decision to create a global variable as opposed to pass a method argument and create a method variable. I find creating local method variables cleans up the remainder of my code by "hiding the overhead", however, I find there is a trade off having to trace and understand the flow of passing method arguments.
Ultimately I believe the best practice comes down to creating minimal overhead by initializing variables at as low a level as possible, essentially:
One should only use global variables where the variable is required in multiple methods.
One should use a method argument and a method variable where the variable is only required in said method and hence is local to said method.
Is that the simple logical way to approach global vs. method variables? Any advice on this line of thought would be much appreciated. As my code begins to grow into hundreds of methods I need to take more care to create my variables in the most logical way.
Thank you for your advice!
Using global variables is considered bad programming practice in most programming languages that I know. You should use params whenever possible. If at all you need something like the singleton pattern.
If you want to store some global thing you should extend Application class, it some kind of session in Android. In this class you can store everything global.
And don't use singleton, it's a bad practice in Android, use Application class.
This is not an easy question to answer in a few sentences. Use of global variables is a bad practice. It leads to tightly coupled code and makes it very difficult to modify or enhance. The need for large numbers of global variables is an indicator that you need to focus on your design.
You mention your code having hundreds of methods. How many classes do you have? If you have hundreds of methods in a single class, that one class has way too many responsibilities. Your design should focus on having classes with clear responsibilities. Each class should have only the data that it needs for handling those responsibilities. This in turn will lead to a reduction in the number of global variables. If the data is clearly the responsibility of one class then it shouldn't be global and accessible to other classes.