Related
I have read many blogs about how singleton are vulnerable in android.so my question is how to maintain such global objects or list in application.i know shared preference is one way but is there any way to maintain such objects or list efficiently.any help will be more helpful.
You can use a file or SQLite database to save data in android app. You can check below links to learn more about saving data in a file or SQLite database:
Saving data to a file is ideal to store long sequences of data that are generally read in order
https://developer.android.com/training/basics/data-storage/files.html
Saving data to a database is ideal for repeating or structured data:
https://developer.android.com/training/basics/data-storage/databases.html
use sharedPreferences, Sqlite database to manage your objects, singletons are not very good, but static variables are more hard to maintain and will make testing the cide more tough, you can use Shared preferences to maintain a global state if the data is not very large, if there is large amount of data then use of sqlite is recommended.
Shared preferences are extremely easy to use, if you have problem using sqlite though you can use orm libraries for android
here's a link to one: http://greenrobot.org/greendao/
If you just want to keep a list as Global until your app is running, then create a new class let's say "Helper" and Initialize a Static List in that class. Now you can access that list anywhere within the app by "Helper.yourStaticListName" and you can also add/remove or get data from the list anywhere within the app.
But if you want to keep that list even when app has been closed, then there are two solutions for that.
First Create a local database "SQLite file" in your app and add/remove or get data from it.
Check this tutorial: http://www.androidhive.info/2011/11/android-sqlite-database-tutorial/
Second solution is to convert your data into a JSON and convert that JSON into String and save it in Shared Preferences. And whenever you need it just get the string from Shared Preferences and convert it into JSON and parse to get the data.
One last thing when you are talking about parsing a JSON, then "GSON library" is a good thing to work with.
Here is the link: http://guides.codepath.com/android/leveraging-the-gson-library
Hope this answer will help you.
How about using Android Service?
You can initialize / start it when your application started (and also stop them when your application stopped) and then bind them whenever you need (put and get your object / list).
I believe it will be an efficient way.
From conceptual point having a static variables or service-locators is very similar to having Singletons. Hence, having them as alternatives may not be be correct, if the intention is to avoid the Global state and consequences.
We can change Singleton-classes into instances, which are instantiated only once and injected into the components and methods as needed. We can use a IoC-framework to handle the injection part or do it manually with a factory pattern to construct (we can restrict only one instance creation as well) instances of the classes. This discussion thread gives lot of insights on the problem and various options.
So if I understand your question right, you need to store some global variables all over your application if that's so please take a look at this question
basically you create a class that extends application which would store anything you would like on start of your app and all of them can be accessed trough out the app.
hope this helps.
If you are trying to create a globally accessible object, the first thing you should ask yourself is: Why? Why do you need a globally accessible object? Most of the time you don't, and you can get away with creating an object with a limited scope which is passed around the app.
There are times when you do want globally accessible resources and using a singleton is just one way to accomplish that. According to the Android Docs your data storage options are:
Shared Preferences
Store private primitive data in key-value pairs.
Internal Storage
Store private data on the device memory.
External Storage
Store public data on the shared external storage.
SQLite Databases
Store structured data in a private database.
Network Connection
Store data on the web with your own network server.
Singletons are great, but the do have their own risks based on how they are implemented. Typically developers use this pattern when you are attempting to share a resource within the application, things like Loggers, Print spoolers, etc. There are multiple ways that you can create Singletons in Java, you can use a Lazy Initialization or Static initialization, each has their own pro/cons. In terms of "vulnerabilities", there are issues with whether or not the singleton is thread-safe, who/what can access it, and so on. This is why it makes sense to try and understand the problem you are trying to solve. Personally, I'm not clear on what exactly you are trying to solve, so I can't really elaborate on how this might help or hurt you. All I can say is that the biggest vulnerability is also it's greatest asset, which is that like most global variables, it can be accessed from anywhere at anytime. There can also be an issue whether or not the singleton is thread-safe.
Personally, I think you need to assess what it is you are trying to solve and the pick the appropriate solution. Maybe using a singleton is the correct solution, maybe it isn't. But understanding all your options and the strength/weakness of each one is going to be the best way to solve this issue. Unfortunately, you haven't provided enough context to your problem for me, or anyone for that matter, to give you a solid recommendation.
The best way to manage global objects is not having them at all. Based on my experience, in a lot of cases there are alternative options instead using singletons. There is so good explained in this post
shared preference is good but some time you will feel problem when do some modification make static constant variable in one pojo java class and use this variable anywhere.because shared preference will not change value after use or unless you dint modify .shared preference retrieving and storing is not very unfriendly. if you use constant you can modify easily .only one class you have to hit
I am working on a j2ee webapp divided in several modules. I have some metadata such as user name and preferences that I would like to access from everywhere in the app, and maybe also gather data similar to logging information but specific to a request and store it in those metadata so that I could optionally send it back as debug information to the user.
Aside from passing a generic context object throughout every method from the upper presentation classes to the downer daos or using AOP, the only solution that came in mind was using a threadlocal "Context" object very similar to a session BTW, and add a filter for binding it on ongoing request and unbinding it on response.
But such thing feels a little hacky since this breaks several patterns and could possibly make things complicated when it comes to testing and debugging so I wanted to ask if from your experience it is ok to proceed like this?
ThreadLocal is a hack to make up for bad design and/or architecture. It's a terrible practice:
It's a pool of one or more global variables and global variables in any language are bad practice (there's a whole set of problems associated with global variables - search it on the net)
It may lead to memory leaks, in any J2EE container than manages its threads, if you don't handle it well.
What's even worse practice is to use the ThreadLocal in the various layers.
Data communicated from one layer to another should be passed using Transfer Objects (a standard pattern).
It's hard to think of a good justification for using ThreadLocal. Perhaps if you need to communicate some values between 2 layers that have a third/middle layer between them, and you don't have the means to make changes to that middle layer. But if that's the case, I would look for a better middle layer.
In any case, if you store the values in one specific point in the code and retrieve it in another single point, then it may be excusable, otherwise you just never know what side affects any executing method may have on the values in the ThreadLocal.
Personally I prefer passing a context object, as the fact that the same thread is used for processing is an artifact of the implementation, and you shouldn't rely on such artifacts. The moment you want to use other threads, you'll hit a wall.
If those states are encapsulated in a Context object, I think that's clean enough.
When it comes to testing, the best tool is dependency injection. It allows to inject fake dependencies into the object under test.
And all dependency injection frameworks (Spring, CDI, Guice) have the concept of a scope (where request is one of these scopes). Under the hood, beans stored in the request scoped are indeed associated with a ThreadLocal variable, but this is all done by the dependency injection framework.
What I would do is thus to use a DI framework, which would make request-scope objects available anywhere, but without having to look them up, which would break testability. Just inject a request-scoped object where you want to use it, and the DI framework will retrieve it for you.
You must know that a servlet container can / will re-use threads for requests so if you do use ThreadLocals, you'll need to clean up after yourself once the request is finished (perhaps using a filter)
If you are the only developer in the project and you think you gain something: just do it! Because it is your time. But, be prepared to revert the decision and reorganize the code base later, as should be always the case.
Let's say there are ten developers on the project. Everybody might like to have its thread local variable to pass on parameters like currency, locale, roles, maybe it becomes even a HashMap....
I think in the end, not everything which is feasible, should be done. Complexity will strike back on you....
ThreadLocal can lead to memory leak if we do not set null manually once its out of scope.
I'm trying to pass data from one activity to another via Intent.putExtras like this:
private ArrayList<HashMap<String, String>> mGroups = new ArrayList<HashMap<String, String>>();
private ArrayList<HashMap<String, String>> mUsers = new ArrayList<HashMap<String, String>>();
...
Bundle data = new Bundle();
data.putInt("mode", mode);
data.putSerializable("groups", (Serializable) mGroups);
data.putSerializable("users", (Serializable) mUsers);
data.putInt("current_class", mCurrentClassId);
data.putInt("current_user", mCurrentUserId);
Intent intent = new Intent(ctx, ChildActivity.class);
intent.putExtras(data);
ctx.startActivityForResult(intent, 0);
Here mUsers is a List of HashMap<String,String> with users' data, including Base64-encoded photo, sum of strings sizes in this list is about 500Kb
Call to startActivityForResult hangs for several minutes with black screen and then I get ANR error. Sub-Activity's onCreate is not called at all.
If I don't add large strings into mUsers (no Base64-encoded photos) - works just fine.
Please help.
if both activities are yours, use a decent data model. Android doesn't encourage that much to very well designed application. Or turn it differently, it allows for fast developped application and doesn't promote much of good software application principle.
The solution of #Jean-Philippe Roy (québec ?) is interesting but singleton are quite an anti-pattern when it comes to more elaborate things, namely statefull models or serviceS.
The best option is to use an application class. This class is your singleton, by nature in android. So,
define an application class in your manifest
provide a static method to access the unique instance of the application class (it is always a singleton).
give it a method to receive and hold your data, call it from your first activity
and a second one to get them back in your second activity
---Updated after #straya's answer and 18 more month of Android programming :)
The question of sharing a data structure or processes accross application, activities, views, fragments is always present at mind when building Android application. It's important to know and consider that the application scope is the right place to hold shared structure, but using the application class itself to put a data structure in that scope is not viable with regards to :
code quality, if all shared data structures and process are know of the application, it will quickly become bloated with accessors for all those entities.
there is only one global shared pool of entities, which is not find grained enough and may lead to hard to detect ways of coupling entities
I now tend to prefer using Dependency Injection managed singletons. Dagger or RoboGuice both allow to create and inject a single instance of a given class into other classes. This technique, and DI more generally offers great possibilities for good Android designs :
don't degrade quality of code, it is even shortened quite a lot. Use #Inject to inject dependencies and they will get injected.
don't give 2 responsibilities to the singletoned class : it will not handle the singleton instance creation, the framework will do it.
it's easier to pass from a singleton to a normal instance
as those singletons become normal classes with a simple annotation, they do not contain static methods anymore and this allows to mock them very easily. And that's a big point.
and of course, DI annotations make it very clear when a class depends on another class, helping to self document code more.
Maximum size is 1MB at Process Level, not at bundle level. This 1MB is for a shared buffer used by all state transactions in progress in the app's process, e.g. onSaveInstanceState, startActivity and others.
On Android 7.0 (API level 24) and higher, the system throws a TransactionTooLargeException when this process level limit is reached. On older versions you only get a warning.
As others suggested, you should research alternatives, if you need to pass a larger payload, e.g. use local database, file system, application level in-memory cache, remote storage, shared preferences (although these need to be small too), etc.
Source of truth: https://developer.android.com/guide/components/activities/parcelables-and-bundles
Just in response to Snicolas' answer:
Application is already a Singleton, no need to "turn it to" one.
Personally, after some serious reliance on Application to hold data for a long time, I've come to not trust it entirely. I use self-caching data objects to mitigate the problems though ;)
I have a simple Android application that uses an instance of a class, let's call it DataManager, to manage access to the domain classes in a Façade-like way. I initially designed it as a singleton which could be retrieved using static methods but I eventually got irritated with the messiness of my implementation and refactored to what I reckoned was a simpler and cleaner idea.
Now the idea is that for each file that is opened, one DataManager is created, which they handles both file I/O and modification of the domain classes (e.g. Book). When starting a new Activity, I pass this one instance as a Serializable extra (I haven't got on to using Parcelable yet, but expect I will when I have the basic concept working), and then I grab the DataManager from the Intent in the onCreate() method of the new Activity.
Yet comparison of the objects indicates that the object sent from one activity is not identical (different references) to the object retrieved from the Bundle in the second Activity. Reading up on Bundle (on StackOverflow, etc.) suggests that Bundles cannot do anything other than pass-by-value.
So what is likely to be the cleanest and safest strategy for passing an object between Activities? As I see it I could
Forget about passing by reference and live with each Activity having its own DataManager object. Pass back the new DataManager every time I close an activity so that the underlying activity can use it. (The simple solution, I think.)
Go back to using a singleton DataManager and use a static method to get it from each Activity. (Not keen on using singletons again.)
Extend Application to create a sort of global reference to DataManager. (Again, not keen on the idea of globals.)
Is that a fair summary? Is there some other healthy strategy I could use?
Another approach would be to create a service. The first activity would start the service and bind to it, when you launch a new intent, unbind the first activity and when second activity starts, bind to the service.
This way you don't have to ever stop the service or worry about passing data between activities.
Java does not have pass by reference so that option is out, I would suggest dependency injection for passing data between the activities. Otherwise definetely the singleton would be the way to go.
The prescribed one is Going by implementing Parcellable interface, thats the way to pass Objects between Activities.. and the 2nd and better choice is to make a Singleton to be sure its single Object.
Create your DataManager as a Singleton that implements Service. Bind the service to your application in the manifest xml (see the link), and you will have a persistent singleton your activities can access without issues.
Passing parcellable arguments can quickly get very messy if you need to get a lot of data. The singleton approach, although usually considered an anti-pattern, works like a charm in cases like these. Just remember to not create multiple singletons that interact with one another.
I would suggest using an Application Subclass. It allows you to hold a single reference to the DataManger class and is persistent as long as your app lives.
A singleton with a static field will also work, but there are some place in the documentation where it says that the content of static fields is not a safe place to store your data. As I understand static fields should persist as long as your ClassLoader stays in memory. Therefore a singleton should only vanish if the whole process leaves the memory and in that case the application class will also leave the memory, but it will call the onDestroy methods of the Application and that enables you to safely close your DataManager and persist important data to memory.
That said to your two variations.
The Android way to go would be to make your DataManager a ContentProvider. This will make it possible to access your Data from every Activity without holding a global reference. I'm not sure how you would build a caching Content Provider that stays in memory and is not reinstantiated too often.
I was just curious where exactly the singleton pattern is used...
I know how the pattern works and where it can be used but i personally never used in any real application.
Can some one give an example where it can be used..
I would really appreciate if some one can explain how and where they have used in real application.
Thanks,
Swati
Typically singletons are used for global configuration. The simplest example would be LogManager - there's a static LogManager.getLogManager() method, and a single global instance is used.
In fact this isn't a "true" singleton as you can derive your own class from LogManager and create extra instances that way - but it's typically used as a singleton.
Another example would be java.lang.Runtime - from the docs:
Every Java application has a single
instance of class Runtime that allows
the application to interface with the
environment in which the application
is running. The current runtime can be
obtained from the getRuntime method.
That's pretty much the definition of a singleton :)
Now the singleton pattern is mostly frowned upon these days - it introduces tight coupling, and makes things which use the singleton harder to test, as you can't easily mock out that component. If you can get away without it, so much the better. Inject your dependencies where possible instead.
Some examples:
Hardware access
Database connections
Config files
I used the singleton pattern in an online Football Team Store System. we applied the singleton pattern to a ShoppingCart class.
You only needed one instance of the cart per an application instance. so the singleton seemed like it's the best fit for that situation.
Consider the situation of AudioDriverService which is designed in Singleton Pattern. So we are allowed to create just a single instance of AudioDriverService class. Now actually your Windows Media Player or Youtube Player both will share the same object of AudioDriverService rather than creating a new instance.
When you use Logger, you use Singleton pattern for the Logger class. In case it is not Singleton, every client will have its own Logger object and there will be concurrent access on the Logger instance in Multithreaded environment, and multiple clients will create/write to the Log file concurrently, this leads to data corruption.
For example running a trial version of a software with one license and one database connection ,that uses singleton pattern in real word. may be the guru jon skeet can provide example like this.
Singleton pattern is generally useful when the object that is created once and shared
across different threads/Applications.
Consider the case that you are implementing the properties load class for a printer.
Now Printers can be of variant properties. For eg:-
Mono Printer,
Color Printer,
Automatic Scanner Support Printer and so on...
Every time on boot this config file has to load to enable a few buttons/ applications
on the UI say tab or any Printer UI.
The value of the supported features are stored in form of a config table like say 1 if
feature supported and 0 if not supported.
Based on the supported features we enable disable certain functionalities and application
on the UI. Now this config file location in case of printers manufactured by a single company
are always stored at a fixed path.
The file values would change/would be read only in the following scenarios:-
1. On Boot.
2. on Addition or deletion of any new hardware peripheral.
We can use a singleton class to implement the reading of configuration files. As the same values
i.e. the config does not change on UI intervention and can be changed only on hardware intervention.
This is one example I can think of where we can implement Singleton design pattern.
Singleton is a nice design pattern. Before deciding on the pattern first do an in depth analysis of your problem and the solution. If in your solution some object has only one instance and you want to model that in your design then you should use singleton pattern. For example if you are modelling a PC in the software there can be only one instance of a PC with respect to your running program. As Jon Skeet said java.lang.Runtime is modelled as a singleton because for all the java objects that are loaded and running inside a java runtime there is only one instance of runtime.
Again lot of times it is used for the wrong reasons. Never create a singleton so that you can easily access the object (like Object::instance() ) from anywhere without passing the object around. The is the worst use I have ever come across.
I use a media player in my android app, so I extend the mediaplayer class, and used the singleton pattern because I need only one instance, and be able to call the same instance in any other part of my app for check if is playing, or what file is current playing.
Hope it helps you, regards!!!!
Singleton Pattern can be used for loading the configuration , say in a web application, we are supposed to generate a file which is to be stored somewhere in the server. Now, that location can fetched from a config file(properties file) using a singleton class.since the location is to be unique and might change frequently in future, so we use a config file so as can be modified without deploying the application so as to reflect the changes and location will be global and unique through out the application
I used a singleton (actually a couple of them) in an application that used pureMVC. We were unhappy about the complexity this framework introduced (it became complicated and tiering to track method calls through the mvc layers). So we used a central singleton as a mediator to better separate the layers from each other.
Singleton Class is basically used when you have to allow only single instantiation of the class.
Taking real world example, In case of OOP designing of a library, we can create library class as singleton class.