Do lambdas in Android N jack compiler hold references to enclosing class? - android

Unlike anonymous inner classes, Java 8 lambdas don't hold references to the enclosing (parent) class. Android N adds support for lambdas.
However, they are implemented in the Jack compiler using anonymous inner classes for backward compatibility, as the note in the link states.
Does this mean that lambdas in Android classes compiled using Jack (and not retrolambda) will hold references to the enclosing class?
I know that one reason many people were excited about lambdas is to avoid Fragment or Activity leaks when using them, but at a cursory glance, it looks like using jack compiler will not give that benefit.

I think the phrase "anonymous class" shouldn't be interpreted too literally here. In my understanding, the only thing they want to tell us is that Jack generates the classes at compile time (as opposed to the runtime approach of Java 8).
From the JackIrBuilder code I'd guess that the generated IR looks very similar to the bytecode that would be generated by retrolambda.
Jack seems to create a synthetic method containing the lambda body in the enclosing type and passes the reference of the enclosing instance to the generated class' constructor only in those cases where it is needed, i.e. when members of the enclosing instance are captured.
Reference: https://android.googlesource.com/toolchain/jack/+/0af676c4779c5b55fb321f491811516f3d74ed93/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
So, from what I understand, the answer is: only when something needs to be captured from the enclosing instance.

Related

Is reflection being used when using the 'is' operator in Kotlin

As MVI is getting more and more popular in Android development, the use of Sealed classes increases as well. And we know that we have to determine the actual type of the Sealed class in order to continue with a particular flow from our logic.
So does Kotlin use reflection when using the 'is' operator for type checks? Tried to go through the documentation, but couldn't find anything about that. https://kotlinlang.org/docs/typecasts.html
Depends on the definition of reflection you’re using. Often “reflection” in the JVM world is used to describe specifically the String-based code meta data inspection from the java.lang.reflect package (or Kotlin reflection dependency) that is considered to be inefficient. But a more general definition of “reflection” is any code introspection. is arguably fits the second definition, but it is fast/optimized and not part of the first definition.
The 'is' operator in Kotlin is used for type checks, for example to check if an object is an instance of a particular class or its subclasses. The 'is' operator does not use reflection to perform type checks. Instead, the type check is done at compile-time, and the generated bytecode contains an instanceof check, which is a standard JVM instruction for performing type checks.
In the case of sealed classes, the use of 'is' operator will not use reflection as well, it's a compile-time check, that's why when using the 'is' operator with a sealed class, the compiler is able to perform type checks and generate the appropriate bytecode at compile-time.
Using the 'is' operator is much more efficient than using reflection, as it is a compile-time check and it does not require any runtime overhead, while reflection can be relatively slow, as it requires the JVM to perform additional lookups and checks at runtime.
So, in summary, the 'is' operator in Kotlin does not use reflection for type checks. It's a compile-time check, which is much more efficient than using reflection.

What does Dagger do? Explain in words that an high-school Java programmer can understand

It is based on the Java Specification Request (JSR) 330. It uses code generation and is based on annotations. The generated code is very relatively easy to read and debug.
1) Dagger provide simplifies access to shared instances
- That means If we declare #Inject annotation in our code then we can get reference everywhere in our projects
2) Easy configuration of complex dependencies
dagger follow the implicit order and generate Objects so in dependency and generated code both are easy to understand and traced and we can reduce large boilerplate of code,
normally we can hand to obtain reference and pass them to other objects so we can focus on modules the build rather then focusing the order in which they need to be created
3) Easier unit and integration testing Because dependency graph is created for us so its easily swap out module,network response

How can I define a custom android annotation (Eg. #Background)

Can any one suggest a proper order to define a custom annotation in JAVA(Android). So that if I annotate a method with #Background annotation, the method should work on background thread.
This might be of use for your need case Creating custom Annotations. It seems like you would need to do #Retention(RetentionPolicy.RUNTIME) and #Target(ElementType.METHOD) scope to achieve what you want. Then as you can see in the first example, you would go into the object and etc.
For a good example, look at what they do in Dagger
As a final note, this is old and you've probably designed what you wanted, but it probably isn't a good idea to do what you asked. There is cost to annotation usage and Runnable was built basically for what you seem to be trying to do.
Android's Annotation subtypes provide a wide variety of tools for what you are trying to do. In particular, take a look at the thread annotations; I suspect that the #WorkerThread annotation does just what you want. The code inspection tools in Android Studio recognize these annotations and will automatically flag any code that it recognizes as violating the threading requirements (e.g., calling a UI thread method from a method annotated as #WorkerThread).
The code inspection tools also allow you to define your own annotations, but these are somewhat limited in what they can do. This is discussed in the section Creating Enumerated Annotations.
You can't use a custom annotation in JAVA(Android), because the android compiler doesn't support it. But maybe the follwing site can be helpful for you: http://androidannotations.org/

Is there documentation on when Dagger falls back to reflection when injecting dependencies?

My team has adopted Dagger for dependency injection within our Android app and I must say that we love it so far. However, we want to make sure that we are using it efficiently. I was wondering if anyone can explain or if there is any documentation explaining the cases in which Dagger falls back to reflection for injecting dependencies?
Dagger's fall-back logic is embedded in its FailoverLoader class. It used to failover when it could not load a ModuleAdapter for a given module, but most recent releases will fail with an error if it cannot load a ModuleAdapter.
Currently, Dagger will fail-over if it cannot find an InjectAdapter class for a given type that needs injecting. The most common case is when you have an abstract parent of an injectable type, that has no #Inject fields. In this case, no InjectAdapter will have been created for it, and so when the concrete injectable type is loaded, it tries to lookup an adapter for the parent, cannot find one, and a reflective stand-in is created.
Similarly, if one does not run code-generation against classes that are decorated with #Inject fields or constructors, Dagger will fall-back to reflection for those as well. It's really the same logic as with the inheritance case above, it's just that inheritance is the only case that doesn't stem from a failure to run the code-generation.
As an aside, the Google fork at http://github.com/google/dagger currently generates adapters that handle their parent types without looking up an adapter for the parent (hard coded parent adapters), so this fail-over does not occur in the google fork. We haven't released the google fork to maven, as it's been nearly identical up until recently, but if failover logic in parent classes is an issue, you may wish to file an issue and ask for a release.

Android: AsyncTask recommendations: private class or public class?

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.

Categories

Resources