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
Related
Square Inc. has presented it's internal modular architecture at Droidcon SF'19:
https://www.droidcon.com/media-detail?video=380843878
However, I'm a bit confused with some bullets. Could you please help me?
Why do they actually need :wiring modules? I find it adding complexity:
you get extra gradle module for each new feature
you have to make a sort of global injection into your Fragments somewhere in :app, because Fragments defined in :impl modules cannot access it's DaggerComponent, which is defined in :impl-wiring modules. :impl doesn't depend on :impl-wiring, because the dependency is reversed.
you cannot have an Android Dynamic Feature modules, because they should know about it's DaggerComponent in order to inject it's Fragment. But there is no way to do such injection from :app module, which is base-module for Dynamic Features.
so why :wiring modules at all?
One can merge :impl and :impl-wiring, or :fake and :fake-wiring together to eliminate all the issues mentioned above. And also, in :demo-apps one could just have a dependency on either :impl or :fake``, and not on :impl-wiring(or:fake-wiring```).
The creation of this type of modules is to separate even more. With this you generate an abstraction of the type of component you use (koin, dagger) and how. If the project is large, it makes sense to do it.
Currently I generate the following flow of dependencies between modules:
WARNING: Check the directionalities well.
:feature-A:open <- :feature-A:impl -> :feature-A:impl-wiring
:feature-A:impl-wiring -> :feature-A:impl, :feature-A:open
:app -> :feature-A:open, :feature-A:impl-wiring
I'm still not sure if app should depend on open and impl-wiring, or which app should only depend on open and open from impl-wiring.
Eventually, I came up with the following solution:
each feature consists of the following gradle-modules:
api
impl and fake
data:api
data:impl1 ... data:implN and data:fake
data:wiring
ui
demo
So, here api, impl and fake as usual, but I've my data layers separated. I bought myself that I need multiple different implementation of data layers sometimes, for example - if I develop Stock-Charts App, I could rely on Finnhub Open API or MBOUM API or provide fake implementation.
Thus I have data:api, data:implX. Indeed, data:api defines FeatureRepository interface (one or many) and data:implX provides actual implementation for them. In order to bind interface and implementation, I use data:wiring, which defines Dagger modules and component(s). In addition, I keep the same package names within each data:implX module in order to "write-once" the data:wiring module. And to replace one implementation with another, I just change a single line in data:wiring/build.gradle which states a sort of:
implementation project(":data:implA")
to
implementation project(":data:implB")
Also, to break the confusion mentioned in my original question, I introduce ui module, which contains some Views of a particular feature. Fragments go in demo (a standalone app to test feature) or in ui, they refer to viewModel which have some bindings ctor-injected from Dagger component of a feature. But the UI and library are separated here. Fragment instantiates a dedicated Dagger component that uses component dependencies to refer to feature's library bindings, such as interactor or repository etc.
So, to wrap up - separation between UI and business logic implementation (a "library") for each feature makes it possible to solve the issue. Feature's api declares an entry point to it's functionality as a library, and it's global access via Dagger multibindings from :app. So it can be used further in any :demo, :ui and :dynamic-feature.
I’m working on a project that is based on the GithubBrowserSample demo application that’s on the Android Architecture Repo on Github.
So far, I was able to inject dependencies to my App, activities and fragments and ViewModels. Also I was able to add more Modules; right now I use two, one for Shared preference and the other a NetModule that has all the mumbo jumbo related to Retrofit/OkHttp.
But here’s the catch: currently the demos that I found that shows how to implement the Retrofit/OkHttp module has a static base URL, which doesn’t work for me since that information is available until the User provide it on the Login section…
Digging around I found that one solution is to create a Submodule (StackOverflow post) with a given Scope Instantiate the component inside my Activity/Fragment. But because I’m using Dagger 2.11 for Android to perform the injection, I have no idea how to do so…
Is there an example that I can look around, or should I give up on this path and take the OkHttp interceptor to change the URL?
Thanks in advance.
I would be creating a library (.aar) at my current workplace. It has a lot of complicated business processes and would definitely need a lot of automated tests, due to which I was planning on using dagger in my library.
But as it is a library, it needs to be as small as possible and depend on as fewer dependencies as possible. Not to mention that dagger just bloats anything it is used with.
So, I am in crossroads and unable to decide what should be my approach.
Can someone please help me come to a conclusion.
there isnt any problem with using dagger in a library if you use the dagger just inside. i mean as long as you dont expect the user of that to provide some dependencies for you from out of the library.
dagger makes the code complicated but not for yourself. assume the person who uses the library knows nothing about DI or dagger.
I myself have some project including a library using a dagger and even needing some dependencies to be provided from out of the library but since the whole project is mine and im not gonna export the library everything is ok.
so this depends how you gonna use it and i suggest if you wanna give this library to others dont expect them to implement dagger and provide some dependencies for you.
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
I started creating a library that will be shared with several projects.
The problem is that the Android documentation is really short about how to handle properly the library projects. I got really stuck dealing with the conflicts between the few classes I have in common in both the main projects and the library project.
I checked the sample from Android (Tic Tac Toe) but it is really too basic to help, but I just remarked that they used the following packages:
The main project: com.example.android.tictactoe
The library project: com.example.android.tictactoe.library
Is the library supposed to be always contained in the main project package? If yes, how to do when several projects have to share the same library project since the main package name belongs to one main project only?
My biggest problem right now is that my app is calling a class from the library project instead of the main project, and I have really no idea what is the best approach to follow.
Thanks!
Update: My question is related to this one: Best practice: Extending or overriding an Android library project class
There are lots of 3rd party libraries available (such as Action Bar Sherlock) and they do not share the same package as yours.
The packages for the library project and the main app project have no requirement of being related in any way.
In some cases it does help having the library as a sub-package of your main app package: this comes from the way you split the project and if the package for your library being a sub-package would help with organising the code, by all means make it a sub-package of your main package; otherwise, don't. It's all about structuring the code in the end.
It is ok for your app to call (actually use would be the work) classes from your library project. That's what libraries are for. They help keep code contained, reusable and decoupled from other pieces of code.
The problem is the other way around: when your library is calling a class from your main project.
The most common approach for Java and Android here is to use an interface: the library provides the interface that the main project implements, then the main project passes an instance of that implemented interface for the library project to use. The best example here would be callbacks. Android provides a set of interfaces (such as View.OnClickListener) that allow you to hook into the system and perform your application's logic (from the application's point of view, the Android classes in the SDK are the libraries).
Other approaches would be providing classes to be extended (this is just like providing interfaces, but it's used when you want to either leave the library user the option of not implementing/overriding all the methods or when you want to keep some base functionality in the object you will be receiving in your library through the use of the final modifier) and reflection (stay away from it as long as possible as it is very error-prone).