I have a question. I have an application that I wrote by extracting data from Api. And I want to add dependency injection to it. Which library will work best and why? How should I choose?
In Android there are multiple libraries to support dependency injection here are few of most used ones by developers.
The ones provided by google are Dagger and Hilt. But they have a bigger learning curve compared to other DI libraries. Still I would recommend to you these in your project.
Hilt is the latest counterpart and is a written over the existing Dagger DI and comes with all the abilities of Dagger hence it is recommended from now on over dagger since it provides a standard way to use DI in your application which was missing in Dagger.
Check out about Dagger from this link
Check out about Hilt from this link
Both the above DI libraries automatically generates code that mimics the code you would have written manually to provide dependency. The code is generated at compile time and therefore if there comes any issue with providing dependency it will be shown at compile time hence avoiding runtime issues regarding fulfilling dependencies.
There are Kotlin specific dependency injection libraries too such as Koin which is more easy to learn and implement compared to Dagger.
Check out about Koin from this link
Koin is usually considered for small to medium sized projects while Dagger and Hilt is considered for medium to large sized projects.
Dagger hilt library is best for dependency injection very less code for injection you can simply inject anything also no need to provide any view model factories for your view models
I have been struggling with providing dependency on Android workers using the dagger2. I have followed numerous blogs about how I can achieve it but I somehow have missed something that I am not able to build my dependency graph with it.
The following is the git repo for the complete source code https://github.com/youranshul/Dagger_worker
The issue I am facing is that how can I provide the dependency which is a part of the activity module but the custom work factory is the part of AppModule.
EDIT 1:
The link github.com/google/iosched provided by #Yavor is a little difficult for me to grab the things keeping my basics in dagger in mind. I have actually looked into the [Dagger from google link][4] and built some understanding of how things work with subcomponents. I have implemented the learning into the mentioned git project and found that I could provide all the dependencies to my worker class. I would like to have a review of my changes and know if I need to improve further on it.
Hoping someone can explain why data binding per module seems not work (returns null) when a specific module/s are declared as runtimeOnly vs when it's declared as implementation.
e.g.
Say I've got some feature modules which I want to include or exclude (similar to dynamic feature modules) except I'm not using that right now for other reasons I will not go into, this is more of an experiment. So the idea was to have multiple components detached from the main application that are only made available at runtime, so in other words virtual no coupling between app and any of the add-on features and this works fine until I add data binding into the mix, crashing with a *Binding cannot be null.
The only way I've gotten this setup to work is by switching back from runtimeOnly to implementation and from what I know so far the difference between runtimeOnly and impelentation are on the gradle website:
So my question is why does this happen, does enabling databinding in modules require the module to be configured with implementation? Or perhaps I'm doing it all wrong and have misunderstood the purpose of runtimeOnly.
Thank you in advance, and apologies if the question is not comprehensive enough
implementation: mostly we use implementation configuration. It hides the internal dependency of the module to its consumer to avoid accidental use of any transitive dependency, hence faster compilation and less recompilation.
runtimeOnly: when we want to change or swap the behaviour of the library at runtime (in final build).
In the case of runtimeOnly, you need two dependencies one which will help you to access the code at compile-time and one which will replace/use at runtime.
Example of Runtime:
SLF4J is one of the best examples of runtimeOnly, where we will use slf4j-api as implementation configuration and implementation of slf4j-api (like slf4j-log4j12 or logback-classic, etc) as runtimeOnly configuration.
I have created a post with an in-depth understanding of each one with Working Example: source code
https://medium.com/#gauraw.negi/how-gradle-dependency-configurations-work-underhood-e934906752e5
I want to use dagger library to android library project. I also fallows How to use dagger in a android library project but does not get proper implementation. Anyone has demo or any Ideas about it ? I also want these library classes extends in project for some changes.
I don't know what the library is, but I would assume most of the code doesn't contain classes with uncontrolled lifecycle (activities, services, fragments, etc.).
If it is true then just use constructors to pass your dependencies.
If it is not then, you have to make a decision who is going to hold knowledge about dependencies graph. A usual solution that context is castable to objects graph knowledge, or it know how to get it. Usually, classes with uncontrolled lifecycle have access to the context
I am evaluating Dependency Injection (DI) frameworks for an Android app. The top contenders are: Dagger (with Butter Knife) and Android Annotations. I understand that Dagger and ButterKnife are from the same source- square and they complement each other. Here're are the key matrices that I am looking for:
Ease of use (our build is based on Gradle and we use Android Studio IDE)
Testing support (we use Robotium for functional testing and RoboLectric for unit testing)
Performance (DI frameworks use reflection, which one is faster?)
AndroidAnnotations
uses compile time annotation processing. It generates a sub class with an underscore apppended to the original name (MyActivity_ generated from MyActivity). So to have it work you always have to use the generated class for references instead of your original class.
It has a very rich feature set, see the list of available annotations.
Butterknife
uses also compile time annotation processing, but it generates finder classes which are used by a central class (ButterKnife). This means that you can use your original class for referencing, but you have to call the injection manually. A copy from the ButterKnife introduction:
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
The feature set is not so rich, ButterKnife supports view injection (AndroidAnnotations equivalent would be #ViewByIdand #ViewsById) and some event binding (for a complete list see the namespace directory here, just count the OnXXX event annotations).
Dagger
is a DI implementation for Android, similar to Guice. It also uses compile time annotation processing and generates object graphs which you use for manually injection. You distinguish between application object graph and scoped object graphs for injecting e.g. in activities. Here you see an Application.onCreate example:
#Override public void onCreate() {
super.onCreate();
objectGraph = ObjectGraph.create(getModules().toArray());
objectGraph.inject(this);
// use injected classes
}
I found it is harder to start with dagger, but this might be only my experience. However see some videos here for a better start: 1, 2
From the feature set point of view I would say that Dagger implements functionalities which could be compared to AndroidAnnotation's #EBean and #Bean functionality.
Summary
If you are comparing ease of use, testing support and performance I can't find much difference between using AndroidAnnotation and ButterKnife+Dagger. Differences are in the programming model (use classes with _ instead of using the original ones and call the injection manually) and in the feature set.
AndroidAnnotation gives you a full list of functionalities, but ties you to certain libraries. For example if you use it's rest api you have to use Spring Android. You also have annotations for features like OrmLite (#OrmLiteDao) regardless if you use OrmLite or not.
At the end it is a matter of taste, at least in my opinion.
Here is the Nice article in Dzone blog.
We to need to compare the features of each, such as :
Minimum Jars required
ActionBarSherlock compatibility
Injection for click listeners
POJO injection
Performance
Only Pojo Injection missing in butterknife! So looks like Butterknife is the winner!
Source
Google does ask specifically not to use dependency injection.
But by reading their request they seem to be referring more to the Guice and reflection based DI library's. Libraries such as android annotation use no reflection instead employing compile time generated code, while butterknife and dagger uses a small amount of reflection optimised for android but are supposedly slightly more powerful than android annotation. It really depends on the project and how much of a performance hit you are willing to take. In my opinion just using butterknife is sufficient to speed up code development by itself. If you need slightly more use android annotation and lastly if you are willing to take a slight performance hit due to reflection the best option without absolutely destroying performance with a powerhouse Guice based reflection use dagger + butterknife.
You should give a try at Toothpick.
Toothpick is (per the README):
pure java
fast, it doesn't use reflection but annotation processing
simple, flexible, extensible & powerful, robust & tested
thread safe
documented & Open Source
scope safe : it enforces leak free apps
test oriented : it makes tests easier
it works very well with Android or any other context based framework (such as web containers)
It can even be faster than Dagger 2 in most cases, and it's much simpler.
Note: Yes, I am one of the authors.
Use Android Annotations or Butterknife to ease your coding. But don't go for Roboguice! Roboguice forces your activies, fragments to extend to roboguice classes. Not fun, at all!
Dagger 2 is a much better option. You can use it along with Android Annotations if you'd like. I would just use Android Annotations for a simple app, but these days is good to work more with Dagger.
Seems like Google chooses dagger, as they are developing it jointly with Square, who created it.
Concerning Butterknife and Dagger themselves, there is the SO question difference-between-dagger-and-butterknife-android which clarifies how they complement each other.
The reddit-thread mentioned by #ChrLipp has someone who used all three on the same project, speaks highly of dagger+butterknife but also gives AndroidAnnotations its place:
For dependency injection, butterknife is used for Views, Dagger is
used for all objects and is highly recommended and Android Annotations
creates more of a framework for developing Android instead of
injecting objects into your classes so each library are quite
different from each other. Dagger is equivalent to Guice but is much
much faster. Dagger is more powerful then ButterKnife and Android
Annotations as it injects all objects rather than ButterKnife and
Android Annotations which only inject a certain set of objects.
Dagger can be a pain to setup and configure but is well worth it once
you have it done. But then again, because these are all quite
different from each other, it all depends on what your needs are for
the project.
Also, speaking of each one being quite different, in your project you
can use ButterKnife, Android Annotations and Dagger all in the same
project if you really want to. They each have the same idea but do
something different so you could use them all.
Eventually if you use one of the three, you'll have a hard time transitioning to Android's databinding. That's what's fastest if you need to consider performance:
https://developer.android.com/tools/data-binding/guide.html