friends,
i have read complete article related to avoiding memory leaks in android.
http://developer.android.com/resources/articles/avoiding-memory-leaks.html
right now
1) i am using private nested class not static
if i make that nested class static will it be usefull?
2) article says
If you're about to use Inner Classes or Anonymous Classes think carefully. Don't use Anonymous Classes until you're very sure and can prove that they are not causing a Memory Leak.
can any one give me example of that? which one is good approach and which one bad for memory leaks.
any help would be appreciated.
1) I would avoid using static classes in general. Especially if you need to pass in the Context pointer, as this will cause a leak. Unless you static classes have on constants, they are analogous to global variables and kinda circumvent the Android architecture which is meant to decouple activities.
Especially you don't want to declare Drawable instances or Android framework objects as static. This messes up their lifetime.
2) I haven't seen any problems with anonymous classes in particular. You may in some cases be able to leak a Context variable, but this is hard to do on a single thread. When passing a context around, you can limit leaks by using getApplicationContext(), which returns the global context which will not leak.
Hope this helps!
Related
I am learning DI with Dagger2 and Hilt and I've got a question:
When creating android app I notice that I use lots of utility classes with static methods(i.e. a function that receives temperature in Celsius and return it in Fahrenheit). BUT, also I use a class (say NetworkUtils) with a static utility method for performing network call to get data from API (as what Android Nanodegree course's instructors were doing):
What I do is like:
class NetworkUtils{
public static String fetchCityName(double latitude, double longitude){
// code for API call
}
}
And now, while I am learning DI principles from Developer Docs, I notice that network calls are made in an instance class within an instance method and its parameters are injected using Dagger.
Why does this make difference from what I was doing?
I read that static methods make testing not easy, however, suppose I used DI like the docs shows,
Why do I have to instantiate a new object of the NetworkUtils whenever I need to perform API call while creating multiple instances is useless?
Also, the official docs says that our use of #Singleton annotation to set function scope (i.e. for a REST API call function) should be very rare, then:
Am I supposed to create instances for everything I need to use even tho it doesn't need to? (except for expensive object instantiation)
Eventually, could you please clarify the difference between a utility class and a normal class that I should not use static methods in it?
Thanks.
And now, while I am learning DI principles from Developer Docs, I
notice that network calls are made in an instance class within an
instance method and its parameters are injected using Dagger.
Why does this make difference from what I was doing? I read that static methods make testing not easy, however, suppose I used DI like
the docs shows,
I see two main reasons:
First, of course, is that the static calls make the code hard to test. But yes, there are some testing frameworks that can do the work for you and mock static calls. But whenever you are using them - it most likely means that you are doing something wrong or you are working with legacy code. This leads me to the second topic.
The idea of TDD - Test Driven Development is that you write the tests first, the code second. But the tests "are not important". Actually, the real result is the better code! The unit test just helps, but they are subproducts. Most of the time there is a high correlation between a good code and a testable code. When you have static calls and singletons it is easy for you to call this code from wherever you want. The result is that you stop thinking about design, about the real OOP principles - what is what. You do not think about extra objects, the relation between objects, etc. And you end up with a spaghetti code. Everything is tied to everything else.
Why do I have to instantiate a new object of the NetworkUtils whenever I need to perform API call while creating multiple instances
is useless? Also, the official docs says that our use of #Singleton
annotation to set function scope (i.e. for a REST API call function)
should be very rare, then:
You are saying something which is contradictory - "creating multiple instances is useless". Obviously creating an instance and not using a static call helps you to achieve better and testable code. Maybe you are wondering if it is a performance hit. Here I will quote.. maybe Martin Fowler... but in his book about Refactoring he is explaining that 9 out of 10 times the optimizations are just useless. You are overdoing it. You need to write good code. Then evaluate. Then if there is a need for optimization - you have the good code - the optimization will be relatively easy.
In your case - do not worry. Wrapping the network calls in instance classes will cause how many instances? 3? 5? It is not a problem when you evaluate the benefits.
About the Singleton - you do not need a shared state - so no need for a singleton. You will shoot yourself in the foot. You will keep things that can be garbage collected, add extra code for singleton creation, etc. Just plain object and that's all.
Am I supposed to create instances for everything I need to use even tho it doesn't need to? (except for expensive object
instantiation)
This is a huge question. You should read a few books and still will not know the answer. Try with Uncle Bob's Clean Code and also Martin Fowler's Refactoring. Then read a few articles of people who think that they are overdoing it and find the balance for yourself. In general, you should no be using "new" and any static calls.. But for example, there are a lot of discussions about how useful are really unit tests on Android and there are a lot of people who tend to go in the direction that you need mostly integration and End to End tests. I will not argue what is the right approach.
4. Eventually, could you please clarify the difference between a utility class and a normal class that I should not use static methods
in it?
Basically, you should not be using "Utility classes". Their idea is to wrap some code, which is used in many places, but there is no state involved. You do not need instance variables so the static methods were a good idea. But it will totally kill your testing. So in your case, you should make one type of class and if you need state - add, if you do not need state - just don't. Then you can call the classes whatever you want.
In Android, it is advisable to refrain from using enum due to performance issue. This is true until recently, where it was announced in Google IO 2018 that enums are now safe to use though avoiding them is still advisable for a more performant app.
My question is:
Can we use kotlin sealed classes extensively in android?
It seems like sealed classes are extensions of enums. If so, should we use sealed classes similar to enums?
Thanks in advance.
The advice to stay away from enum on Android is exaggerated. Avoiding enums makes sense for the Android APIs: they heavily use special constants, there are very many of those objects live in an application, and they are performance-critical.
Your custom application code would probably want to use just a few enums to express entities from business logic. Creating a dozen, or even a few hundred, enum instances will leave an imperceptible footprint.
The same advice extends to sealed classes: by all means use them and improve the quality of your code. Stop to think about your choice only if you plan to embark on building a 100 KLOC application with thousands upon thousands of enum-like constants and classes.
Enums
Garbage Collection
Under the hood, enums are static members of the class, so they don't get garbage collected. They stay in memory for the lifespan of your app. This can be an upside or a downside.
The garbage collection process is expensive in terms of CPU usage. The same is true for object creation, you don't want to create the same objects again and again. So, with enums, you save the cost of garbage collection as well as object creation. This is the upside.
The downside is that the enums stay in memory even when they are not in use, this can keep the memory occupied all the time.
Factors to Consider
You don't need to worry about all this, if you have 100 to 200 enums in your app. But when you have more than that, you have a decision to make whether you should go for enums depending on the facts such as the number of enums, whether they will be in use all the time and the amount of memory allocated to your JVM.
Comparison
The comparison of enum values is faster in the when expression because under the hood it uses tableswitch to compare the objects.
Android
In Android, when the optimization is enabled, the Proguard converts the enums that don't have functions and properties to integers. This way, you get the type-safety of the enums at compile-time and the performance of the ints at runtime!
Sealed Classes
Garbage Collection
Sealed classes are just regular classes with the only exception that they need to be extended in the same package and the same compilation unit. So, their performance is equivalent to regular classes.
Objects of the subtypes of the sealed classes get garbage collected like the objects of regular classes. So, you have to bear the cost of garbage collection as well as object creation.
Factors to Consider
When you have the low memory constraints, you may consider using sealed classes instead of enums, if you need thousands of objects. Because the garbage collector can collect the objects when the memory is low and the objects are not in use.
If you use object declaration for extending the sealed class, the objects act as singletons and they won't be garbage collected, this behaviour is similar to enums. But there is an additional cost of loading the associated classes and keeping them in memory because object declarations have associated classes with the same names as the objects under the hood.
Comparison
The comparison of sealed class' types is slower in the when expression because under the hood it uses instanceof to compare the types. The speed difference between enums and sealed classes, in this case, is very little though. It matters only when you are comparing thousands of constants in a loop.
Android
Proguard doesn't have any integer optimization like enums for sealed classes. So, if you want to have just constants without functions and properties in Android, sticking to enums is a better idea.
That's it! Hope that helps.
The performance impact of sealed classes is the same as for any other classes. If you create an instance of a class extending a sealed class, it will be a new instance, so it will need to be garbage-collected. If you have an object extending a sealed class, it will be a singleton and will not need to be collected (just like an enum constant)..
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'm currently developing some Android Apps in a team and we've used 2 different approaches during the last months (one that i personally prefere, and the other that the other developer prefers).
Although so far the results are the same, this got me wondering...should we:
use AsyncTasks as private classes inside the Activities that use them.
or use AsyncTasks as separate public classes that receive the context of the activity
Are any of the approachs recommended by Google?
What does your experience say about this (advantages, disadvantages, problems)?
Inner classes are good for representing objects that are meant to be private or somehow intimately tied to the enclosing class. Occasionally there are technical reasons for using inner classes (e.g., simulating closures). They also cut down on namespace pollution.
One disadvantage of inner classes is that if they access private members (fields or functions) of the enclosing class, the compiler will generate accessor functions to those members. Language purists will argue whether this breaking of encapsulation is a Good Thing or a Bad Thing. The access functions add a bit of overhead to each access (which usually isn't a factor, but there it is). Another disadvantage is that it makes the source file more complex and therefore harder to manage. (I've occasionally been stung by editing a function in the inner class while thinking it was in the outer class, and vice versa.) Finally, inner classes tend not to be reusable, while separate classes can often be parameterized to have multiple uses.
These pros and cons are off the top of my head. I'm sure others will have additional thoughts.
UPDATE:
In this Google IO video the inner AsyncTask option is clearly marked as wrong option.
It doesn't matter, use what makes the most sense for your code. The important thing is to watch for an async task that is holding a reference on an activity after the activity has been destroyed, either implicitly as an inner class of the activity, or explicitly by being given the activity/context object.
How do I make application context available to all classes in application in the app?
My supporting classes need to be able to access it in order to access resourses.
Best answer: pass in a Context to your supporting classes' methods, as the application context may or may not work for your particular cases. You will notice, for example, that many supporting classes in Android take this approach, and it is generally a good idea to follow the patterns set forth by the platform developers.
Possibly tolerable answer: use a static data member to hold a reference to the Application object. Be very very careful that you do not introduce memory leaks in the process.