I am aware of the technique of extending the Application class to provide global storage. However in my case I am writing a class for a library function, so do not wish to force users of the class down this path. I have a requirement for some static class variables. I have seen passing references in StackOverflow that these might not be safe. However I've tried two different applications using the same class, and even when running both applications side by side on a Galaxy S3 in multi-window mode, the static class variables remain separate.
So, can someone with an in depth knowledge of Android internals confirm if this is safe or not.
If it is not safe, I can wrap the variables in a nested class and add them to a Serializable static HashMap, using the application package name as the key. This will force them to be safe. However if this is not necessary, then I'd rather not do it.
I have seen passing references in StackOverflow that these might not be safe.
They are not "safe" insofar as your process will be terminated from time to time, wiping out your static data members (and your custom Application, for that matter). Hence, static data members are good for a cache and not much else.
Within that scope, they are "safe".
You just need to make sure that this data is either stored somewhere persistent (e.g., file) or otherwise can be regenerated once the process is terminated and later is started up again. This is no different than with Application.
However I've tried two different applications using the same class, and even when running both applications side by side on a Galaxy S3 in multi-window mode, the static class variables remain separate.
Correct. Those are separate processes, with separate copies of your class and objects.
If your goal is to store persistant data across the twists and turns of the application lifecycle, then I would recommend not using static variables to do so. The obvious problem with this approach is that they could easily be garbage collected by the system when the operating system decides to reclaim memory (i.e. when the screen sleeps or a different application starts a memory-intensive task). I'm not sure what kind of data you are looking to "store", but I would recommend saving the state in SharedPreferences or an SQLiteDatabase instead.
I'm a little confused about what you're trying to do. You're trying to create a utility library in Java to be used by other applications? You're trying to create a whole Activity intended for use by other applications?
At any rate, as other posters have mentioned, applications can be killed at almost any time when resources become tight. There's simply no way to guarantee that static global values will remain resident in memory. You must provide a way to back it up on onPause() or onSaveInstanceState().
If you're writing a utility library, I presume that it returns some master object which holds all of its state. Add saveState(Bundle), restoreState(Bundle) methods to that object, and optionally saveToSharedPreferences() and restoreFromSharedPreferences() methods as well.
If it's an Activity you're writing, you're probably already familiar with the ways of saving state.
Me, I'm fond of combining the "singleton pattern" with shared preferences: https://stackoverflow.com/a/13673178/338479
You seem to have a deep misconception of how classes work.
Even if two classes are in the same package in two separate apps (by default) those apps run on separate VMs (i.e., processes). They literally have nothing to do with each other (as it should be, since otherwise you might get cross-app name collisions which is unacceptable).
What you're looking for is not a way to use static variables but a way to do inter-process communication (IPC). Android's Services are ideal for this, though there is a bit of a steep learning curve there.
Related
Storing state inside the Application class or a singleton has the added benefit of sharing across activities too (is there a simple way to share one ViewModel across two activities I'm unaware of?)
Also a singleton can be as android free as a ViewModel can be, so testing locally (without an android device or emulator) shouldn't be an issue.
Storing state inside the Application class or a singleton has the added benefit of sharing across activities too
It is also a memory leak. Use that for things that are truly process-wide, and make sure that you are taking steps to cap the memory use (e.g., limit the size of any caches that you use).
What's the benefit of storing state in ViewModel (from Android Architecture Components) rather the Application class or a Singleton?
A ViewModel, retained fragments, and onRetainCustomNonConfigurationInstance() are for holding state unique to a running activity, across configuration changes for that activity. At most — if you screw something up — they temporarily cause a memory leak, but that will get cleared up as soon as the overall activity is destroyed. Also, because these are scoped to an individual activity, you can easily have N of them for N logical activity instances, which may or may not be practical with process-wide solutions.
In general, in computer programming, we aim to keep our data in the narrowest scope possible ("information hiding"). Using things that are global in scope runs counter to that design principle. Hence, using singletons is possible, but should be reserved for cases where it is unavoidable or vastly superior to using a narrower scope. In Android, we use singletons far more than you would in ordinary Java development, where singletons are often considered to be evil.
I have an android app which encrypts and uploads various files to AWS. The boiler plate code for AWS is a singleton, and I use that throughout my app. I have an encryption class as well, and I am currently instantiating encryption objects in various places, encrypting the file, and passing it to the singleton instance of the AWS upload class.
I am wondering if this is the best approach? Should i make the instance of the encryption object static? And have just one instantiated, and then call the encrypt method from different classes? In some places it is recommended, in others people say using static can be dangerous? Or is there a better way than either of these options?
Should note the app works fine as is, but I am a self taught Android dev, and I am trying to get better, but none of the tutorials go into heaps of detail about things like this.
Static is not dangerous, it's to share operations that don't depend on instances of objects. Like the Math class.
Singleton pattern is for controlling instances of objetcs of some class. If you want an instance, and only one instance, you use singletons. Generally, people use it to get that instance at a global scope. I think the Application class would fit this.
I prefer to use dependency injection if I am working with a lot of service classes. Encryption is a service to me, but you have to do the mechanism for dependency injection, or use a framework, but this is overkill to your problem.
I would go for the static methods this time.
Creating a Singleton class or making your object static, both are good options if you have to use the method of a class on various places. It's better to have a static object then creating the same object again and again.
So according to me the "Singleton" class is the best option to make your code efficient, but if you want to go with a static method/class then there is no harm in it. Static can be dangerous in some situations, like when you have to assign different values and get different values in different situations. Then there is a chance you can get wrong value in wrong situation. But in your case it's fine.
I can't find some informations about android application (not activities) lifecycle. My question is, how the application is working, when I treat it like a java programm - when it's initializing for example static objects. I'm adding a small graphic, that is showing my point of view - I'll be greatfull if someone could tell me, if I'm thinking correct :-)
For the application lifecycle, as per Android API Guide:
By default, every app runs in its own Linux process. Android starts the process when any of the app's components need to be executed, then shuts down the process when it's no longer needed or when the system must recover memory for other apps.
For static objects, they are initialized only once and are initialized when the class (which they are member of) gets loaded by ClassLoader. They will remain in memory until the class is unloaded. To read more about it, check this SO question
For activities, they have a clear lifecycle.
I saw several places and people suggesting extending the Application class in their app.
Personally, I have never needed the necessity to do so.
I was not able to find a clear cut and direct answer by google-ing, so here are some questions :
What is an application class ?
why do we need it ?
Is it a singleton ? or we can have several instances ?
When we use it inside our manifest, is it the same as using the default application that usually eclipse generates ?
When are cases that extending it might be needed ? and when it is an overhead ?
Is it useful for caching purposes ?
It is something I have also thought about when I first started developing with Android and never came up with an answer. However just a quick google myself revealed this website.
Essentially I think it comes down to the fact if you are making a more involved Android application which would involve several Activity classes then things become difficult if you need to persist data that is to be shared between the various Activity classes of your application. Quoting from the above website:
If you take a look at the Application class (see here) in the API reference guide, you get a suggestion on how to manage global application data. The Application class, it says, is the “Base class for those who need to maintain global application state.”
If you've just started Android development this point may not be apparent to begin with however once you've worked with SDK for a while and you come up with an idea that you'd like to develop in a serious way you may hit upon this problem and then the reason for the Application class will become clear.
In the Android documentation there is quite good explanation what the Applications.class is.
Base class for those who need to maintain global application state. You can provide your own implementation by specifying its name in your AndroidManifest.xml's tag, which will cause that class to be instantiated for you when the process for your application/package is created.
There is normally no need to subclass Application. In most situation, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.
Sometimes you may need it to extend in order to work with external libraries. I did use it for UrbanAirship see here
The Application instance is indeed one for our app and it is created when our application starts and removed when it is closed. It represents general state of the application.
Even a private member/function of my class can be accessed by reflection by using setAccessible(true). Is there a way to prevent this kind of access from outside code?
I read something, here on stack-overflow, that I can use SecurityManager for prevention of reflection in applets(not sure how it works, though), but is there a similar mechanism for Android as well? Maybe an annotation or clever-programming?
Taking a step back, what you're observing is a difference in security philosophy, between the Java execution model as originally embodied in JVMs at Sun and the execution model of Android.
The original Java VM design was intended for a system wherein multiple, mutually-suspicious applications (or "applets" in the Java parlance) would simultaneously inhabit a single address space, running in a single VM. Because the designers didn't want one app to be able to mess with another, they went through great pains to define an intra-VM security model that would disallow things such as one object touching the private fields of another object of a different class.
That said, the Java library ended up having various "escape hatches" out of the security model. One of those is setAccessible() on reflection objects, as you note.
Android's model is different: Android uses processes as the security boundary and unit of application isolation, instead of trying to insinuate it into the process as was done with traditional JVMs. This renders moot the entirety of the Java security model, except in that it helps an application "save it from itself." That is, it's good design to not have an object poke into another object's private parts, and the default Java security model provides just that.
Leaving aside the question of people modifying your code, with Android, as an application author, you control all the code that ends up running inside the process of your app. If you choose to include code that calls setAccessible() that's your business. You might be shooting yourself in the foot, but you certainly won't be shooting any other apps' feet, since the Android security model, running as it as at the layer of processes, inherently doesn't let that happen. Likewise, using native code will totally break you out of the Java object model, which allows for the possibility of things going totally higgledy-piggledy in the process but also allows you to express some things in a more productive manner than you could in Java. It's a trade-off, but it's a per-application-developer tradeoff and not one that particularly impacts anything else that's happening on your phone / device.
I know this doesn't directly answer your question, but I hope it provided some useful context.
Is there a way to prevent this kind of access from outside code?
Not really.
is there a similar mechanism for Android as well?
Even if there is (and I am not aware that such a thing exists), anyone can remove it, by decompiling your code (assuming they do not have your source already), getting rid of the protection, and recompiling the code.
Bear in mind that ProGuard, when used properly, will obfuscate your private classes and methods for your production APK builds. That, plus a lack of documentation, will make it tedious for anyone to gain access to those private classes and methods.
I don't believe that you can ever really 100% protect from users using reflection on your project with malicious intent. You can make it more difficult for users to do it by doing things like obfuscating your code, but it is still possible to reflect on the obfuscated code.
I don't believe SecurityManager can be used for the purpose that you are suggesting, though I could be wrong.