Do companion objects remain in memory for app's lifecycle - android

In Kotlin, you can create a singleton using a companion object:
class MyClass {
companion object {
fun doSomething() {
}
}
}
According to the Kotlin docs, it states:
Note that, even though the members of companion objects look like
static members in other languages, at runtime those are still instance
members of real objects...
https://kotlinlang.org/docs/reference/object-declarations.html
Does this mean that after using a function in the companion object, the instance of the class (MyClass) remains in memory for the entire lifecycle of the app? Is there a way in Android Studio to check to see if this is the case?

instance of the class (MyClass) remains in memory for the entire lifecycle of the app?
Companion object in JVM
in kotlin
class MyClass {
companion object {
fun doSomething() {
}
}
}
MyClass(Kotlin) converted in JVM
public final class MyClass {
public static final MyClass.Companion Companion = new MyClass.Companion(null);
public static final class Companion {
public final void doSomething() {
}
private Companion() {
}
public Companion() {
this();
}
}
}
As above code, companion object is declared as Companion class in JVM, and it's created as static field inside MyClass class. Thus, isn't collected by gc. So, the memory of object(Companion) is remained during the ProcessLifecycle. static final object isn't released in normal case.
In conclusion, if referred to MyClass.Companion instance in application, that instance will not be garbage collected. (on general Classloaders).
*If not referred to MyClass.Companion instance in application, it may be removed by code shrinking feature.
Is there a way in Android Studio to check to see if this is the case?
You can see through android studio > profiler > Heap dump.
Reference
https://developer.android.com/topic/performance/memory-overview
https://developer.android.com/studio/build/shrink-code

As you seem to know and the above answer also makes clear that companion objects are translated to classes, and the class which declares them holds a static reference to the object of companion class, something as following:
public static final MyClass.Companion Companion = new MyClass.Companion(null);
Now the question
Do companion objects remain in memory for app's lifecycle
because the declaring class holds a static reference to companion class, the question reduces to the life time of static fields in jvm class and the answer lies in the JVM spec, but the spec is bit dry on the explanation so I am adding some snippets from the book Inside the Java Virtual Machine.
As in your example let say we have a class with nothing but single companion object.
First question is when an object of companion class will be created ? or
when static fields are initialized ?
relevant text from the book. (for context the book is talking about class loading procedure)
Initialization
The final step required to
ready a class or interface for its first active use is initialization,
the process of setting class variables to their proper initial values.
As used here, a "proper" initial value is the programmerís desired
starting value for a class variable. A proper initial value contrasts
with the default initial value given to class variables during
preparation. As described above, the virtual machine assigns default
values based only on each variableís type. Proper initial values, by
contrast, are based on some master plan known only to the programmer.
In Java code, a proper initial value is specified via a class variable
initializer or static initializer.
So we know that once MyClass is loaded and initialized, the object of companion class will be created.
but what would cause JVM to load MyClass ?
The Java Virtual Machine specification gives implementations
flexibility in the timing of class and interface loading and linking,
but strictly defines the timing of initialization. All implementations
must initialize each class and interface on its first active use. An
active use of a class is:
The invocation of a constructor on a new
instance of the class
The creation of an array that has the class as
its an element type
The invocation of a method declared by the class
(not inherited from a superclass)
4 The use or assignment of a field
declared by the class (not inherited from a superclass or
super interface), except for fields that are both static and final, and
are initialized by a compile-time constant expression
So as per 4th point when you do MyClass.foo() from kotlin or MyClass.Companion.foo() at this point MyClass will be loaded and ready. (Probably a lot early)
Please note that at this point no object of MyClass exist, that is we haven't used expression MyClass().
Does this mean static fields will remain in memory as long as the application is running ?
They can be garbage collected if the declaring type gets unloaded, in our case if JVM or ART (on android) unloads the MyClass then there is a possibility that companion object will be Garbage collected.
JVM Spec has following to say about class unloading
An implementation of the Java programming language may unload classes.
A class or interface may be unloaded if and only if its defining class
loader may be reclaimed by the garbage collector as discussed in
§12.6.
Classes and interfaces loaded by the bootstrap loader may not be
unloaded.
In practicality class unloading almost(I said almost) never happens, so yes companion objects will remain in memory for app's life cycle.

Related

Kotlin and jvm: object OR class instance?

object SampleObject{
fun getSampleText(): String = "123"
}
class SampleClass {
fun getSampleText(): String = "123"
}
There are no fields, methods only.
ActivityA starts ActivityB.
In ActivityB there is a call to SampleObject.getSampleText() and SampleClass().getSampleText(). Then ActivityB finishes.
What is the best practice? To use object or to use class instances?
If the function is pure (i.e. no side-effects), then code it at the top-level. No need to explicitly create a class/object in Kotlin.
The compiler will produce a class that contains your method as a static method, and therefore has the same lifecyle as all static methods.
An Object contains a static reference to a constructed version of itself, and the class has your function. Again, the class/method will exist for life of JVM

Are static methods a bad pratice? [duplicate]

I have a class that consists only of static member variables and static methods. Essentially, it is serving as a general-purpose utility class.
Is it bad practice for a class to contain only static member variables and static methods?
No, I don't think so at all. It is worse practice to have a class full of instance methods which don't actually depend on a particular instance. Making them static tells the user exactly how they are intended to be used. Additionally, you avoid unnecessary instantiations this way.
EDIT: As an afterthought, in general I think its nice to avoid using language features "just because", or because you think that that is the "Java way to do it". I recall my first job where I had a class full of static utility methods and one of the senior programmers told me that I wasn't fully harnessing the OO power of Java by making all of my methods "global". She was not on the team 6 months later.
As long as the class has no internal state and is essentially what is known as a leaf class (utility classes fall into this category), in other words it is independent of other classes. It is fine.
The Math class being a prime example.
Sounds reasonable.
Note: Classes that do this often have a private no-arg constructor just so that the compiler yields an error if a programmer tries to create an instance of the static class.
Static methods don't worry me much (except for testing).
In general, static members are a concern. For example, what if your app is clustered? What about start-up time -- what kind of initialization is taking place? For a consideration of these issues and more, check out this article by Gilad Bracha.
It's perfectly reasonable. In fact, in C# you can define a class with the static keyword specifically for this purpose.
Just don't get carried away with it. Notice that the java.lang.Math class is only about math functions. You might also have a StringUtilities class which contains common string-handling functions which aren't in the standard API, for example. But if your class is named Utilities, for example, that's a hint that you might want to split it up.
Note also that Java specifically introduced the static import: (http://en.wikipedia.org/wiki/Static_import)
Static import is a feature introduced
in the Java programming language that
members (fields and methods) defined
in a class as public static to be used
in Java code without specifying the
class in which the field is defined.
This feature was introduced into the
language in version 5.0.
The feature provides a typesafe
mechanism to include constants into
code without having to reference the
class that originally defined the
field. It also helps to deprecate the
practice of creating a constant
interface: an interface that only
defines constants then writing a class
implementing that interface, which is
considered an inappropriate use of
interfaces[1].
The mechanism can be used to reference
individual members of a class:
import static java.lang.Math.PI;
import static java.lang.Math.pow;
or all the static members of a class:
import static java.lang.Math.*;
While I agree with the sentiment that it sounds like a reasonable solution (as others have already stated), one thing you may want to consider is, from a design standpoint, why do you have a class just for "utility" purposes. Are those functionals truly general across the entire system, or are they really related to some specific class of objects within your architecture.
As long as you have thought about that, I see no problem with your solution.
The Collections class in Java SDK has static members only.
So, there you go, as long as you have proper justification -- its not a bad design
Utility methods are often placed in classes with only static methods (like StringUtils.) Global constants are also placed in their own class so that they can be imported by the rest of the code (public final static attributes.)
Both uses are quite common and have private default constructors to prevent them from being instantiated. Declaring the class final prevents the mistake of trying to override static methods.
If by static member variables you did not mean global constants, you might want to place the methods accessing those variables in a class of their own. In that case, could you eleborate on what those variables do in your code?
This is typically how utility classes are designed and there is nothing wrong about it. Famous examples include o.a.c.l.StringUtils, o.a.c.d.DbUtils, o.s.w.b.ServletRequestUtils, etc.
According to a rigid interpretation of Object Oriented Design, a utility class is something to be avoided.
The problem is that if you follow a rigid interpretation then you would need to force your class into some sort object in order to accomplish many things.
Even the Java designers make utility classes (java.lang.Math comes to mind)
Your options are:
double distance = Math.sqrt(x*x + y*y); //using static utility class
vs:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
Even if we were to avoid the verbose method, we could still end up with:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
in this instance, .sqrt() is still static, so what would the point be in creating the object in the first place?
The answer is, create utility classes when your other option would be to create some sort of artificial "Worker" class that has no or little use for instance variables.
This link http://java.dzone.com/articles/why-static-bad-and-how-avoid seems to go against most of the answers here. Even if it contains no member variables (i.e. no state), a static class can still be a bad idea because it cannot be mocked or extended (subclassed), so it is defeating some of the principles of OO
I wouldn't be concerned over a utility class containing static methods.
However, static members are essentially global data and should be avoided. They may be acceptable if they are used for caching results of the static methods and such, but if they are used as "real" data that may lead to all kinds of problems, such as hidden dependencies and difficulties to set up tests.
From TSLint’s docs:
Users who come from a Java-style OO language may wrap their utility functions in an extra class, instead of putting them at the top level.
The best way is to use a constant, like this:
export const Util = {
print (data: string): void {
console.log(data)
}
}
Examples of incorrect code for this rule:
class EmptyClass {}
class ConstructorOnly {
constructor() {
foo();
}
}
// Use an object instead:
class StaticOnly {
static version = 42;
static hello() {
console.log('Hello, world!');
}
}
Examples of correct code for this rule:
class EmptyClass extends SuperClass {}
class ParameterProperties {
constructor(public name: string) {}
}
const StaticOnly = {
version: 42,
hello() {
console.log('Hello, world!');
},
};

How should I pass around singleton objects to Android activities?

I'm developing an Android app that uses two singleton objects: one for business logic (similar to the model in MVC) and one for a Bluetooth connection. Some activities display data and need access to the former, while one lets the user connect/disconnect and needs access to the latter.
What is the preferred way of passing these objects around? Arguments to the activities? Global objects?
You can use Application Class. it is a 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 ,the function to retrieve it can be given a Context which internally uses Context.getApplicationContext() when first constructing the singleton.
ref- http://developer.android.com/reference/android/app/Application.html
Ex- Define in App class
public class AppData extends Application{
Object ob = new Object(); //Global Obj - Can be anything String etc
}
initialize in acticity like -
AppData ad= (AppData)getApplicationContext();
ad.ob = //yourValue
Access across the activities ->
Object obj = ((AppData)getApplicationContext()).ob;
and in manifest give the name of your app class-
<application
android:name=".AppData"
>
You might want to check out Dagger. This Dependency Injection framework (optimized for Android) allows to easily inject singletons into your activities/fragments.
// define this code in your common data access class which use thought your app or application master class
private static Object object=null;
public synchronized static Object getInstance(){
if(object==null){
object = new Object();
}
return object;
}
// this way define your two object.

Implementing Parcelable interface on polymorphic arrays

I have an array of type named ItinerarySegment, and this type has subclasses: WalkSegment, BusSegment etc.
public interface ItinerarySegment
{
}
public class WalkSegment implements ItinerarySegment
{
}
public class BusSegment implements ItinerarySegment
{
}
What sort of strategy should I follow when making the array of ItinerarySegment parcelable? The main concern here is how it will be used later when re-constructing the array via the createTypedArray method (prepared by writeTypedArray method).
In which the createTypedArray method take a Creator field parameter. The problem lies here...Where should the Creator field be defined? (in ItinerarySegment, WalkSegment, or BusSegment?).
public static final Creator<Typename> CREATOR = new Parcelable.Creator<Typename>()
{
public Typename createFromParcel(Parcel in)
{
return new Typename(in);
}
public Typename[] newArray(int size)
{
return new Typename[size];
}
};
If I make ItinerarySegment an abstract class and define the Creator field's method, then the subsequent subclasses's data will be lost since neither of their constructors are called with the Parcel parameter, instead ItinerarySegment's constructor will be called.
constructor(Parcel in);
If I make WalkSegment define Creator field, then BusSegment would have a problem.
Any clarification needed?
In order to do this using writeTypedArray() and createTypedArray() you would need to make ItinerarySegment an abstract class, not an interface. ItinerarySegment would need to implement Parcelable and it would need to have a CREATOR defined that would be called to unmarshall the Parcel and create new objects. Derived classes would also need to implement the methods writeToParcel(), describeContents() and the CREATOR.
NOTE: Because writeTypedArray() does NOT write the type of the object into the Parcel, you will need to do this yourself. Here's 2 possible ways:
The writeParcel() method of each derived class would have to write something to the Parcel at the very beginning that identifies its type (a String or int value).
The writeParcel() method of each derived class would have to call super.writeToParcel() before writing anything to the Parcel. In the ItinerarySegment.writeToParcel() method you could figure out what type of derived class it is and write something to the Parcel that identifies its type (a String or int value).
The CREATOR in ItinerarySegment would first read the identifier from the Parcel and then using that, determine which type of object to instantiate. It would then call the corresponding object's CREATOR to actually instantiate the object and return that to its caller.
This basically works like an object factory, in which the base class knows how to instantiate different types of its own derived classes.
The downside of all this is that the abstract base class would have to know about all of its derived classes. I suppose you could also do this dynamically, by have all derived classes call a static method in the base class passing its "type" and CREATOR, which the base class would then store in an array to be used as needed.
All doable, but pretty complicated.
As an alternative you can use writeParcelableArray() and readParcelableArray(), where the class name of each object is written to the Parcel so that it knows which CREATOR to call when unmarshalling.
IMHO the only time to use writeTypedArray() and createTypedArray() is when all the objects in the array are instances of the same class, and you are writing more than a handful of them into the Parcel. In that case, you save the overhead of writing the class name into the Parcel for each object, as you know they are all the same. In this case you don't need to go through all the agony I described above because you know the type of all objects beforehand (no polymorphic types).
I realize this answer is probably more than a year late, but what the heck. Maybe it will help someone else ;-)

Instantiate variables in class instead of onCreate() wrong?

Is something wrong with this construct in Android?
class A extends Activity {
private Object myObject = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
//myObject = new Object();
}
}
Because at some point(s) later I get (sometimes, not reproducible yet) exceptions because myObject is null. I don't know if it's because I have to initialize in onCreate.
Edit: Additional details:
The actual class of myObject is List<Object> (Where Object is a domain specific type)
At some point later in the activity I'm storing myObject as a static field of a "Parameter passer" class and starting other Activity (because I'm avoiding to implement Parcelable. If this is good or bad practice should not be discussed here, unless that's causing my error). In the other Activity I pick up myObject. There it's (sometimes) null.
Edit 2: I don't understand why this object becomes null if I'm storing a reference to it as static field of my parameter passer class (a standalone, dedicated class). That's how garbage collection works, right, it just removes when the objects are not referenced anymore. So since I have a static reference this object should not be removed. According to this thoughts, if they are correct, the problem should be somewhere else.
When you start a new activity your old one goes on the block for possible garbage collection (including any classes instantiated in it, including your parameter passer class), so your object is not necessarily going to be available (which is why you see an intermittent failure.).
I see two option:
1) Pass it along in the bundle with your intent that starts the new activity. As you were trying to avoid this, probably not your best choice.
2) Extend the Application class and store the object in there.
EDIT
I think the accepted answer to this SO Question might fix your issue (and explain what is actually happening).
No. That code is just fine. You can create objects in the constructor.
You may want to check a previous question about it Instance variable initialization in java and the section 3.2.4. Field Defaults and Initializers which basically states that the first case:
private Object myObject = new Object();
is identical to an initialization in the class constructor. (NOTICE onCreate is NOT the constructor).
So, myObject should never be null, except in the case the "new Object()" instruction failed, generating an exception.
Isn't this possible your code is changing the contents of myObject later on the code?

Categories

Resources