I am trying to you use Android Annotations (https://github.com/excilys/androidannotations) in an existing project. I cannot convert the whole project to use Annotations. Can I have some activities that utilize annotations and some acitivites that doesn't use Annotations.
But When I did that, some functionalities stopped working. Like If I used only -
#ViewById(R.id.find)
public Button FIND;
...
...
#Override
protected void onCreate(Bundle savedInstanceState) {
...
if (FIND != null) {
FIND.setOnClickListener(this);
}
...
}
OnClick on the button doesn't work. Is it mandatory to use #Click annotation.
Can't I just use annotations only where I wish to have. And other parts of the code be the old code without annotations. Please guide me.
Thanks
Please read the doc more carefully. The injected views are first available in the #AfterViews annotated methods:
#AfterViews
void afterViews() {
// you can use injected views here
}
https://github.com/excilys/androidannotations/wiki/Injecting-Views#afterviews
First of all please respect coding convention, you can find ax explanation here
Then, for your question, you can use code of both types: native android and android annotations one.
If you inflate a view using #ViewById annotation, you must keep in mind that the injection of the view is done at a certain point of the execution, so before of that your variable will be null.
As WonderCsabo reccommended to you, use injected views inside of #AfterViews annotated method.
Otherwise, if you want to mantain android native syntax, you MUST instantiate your view manually with findViewById method. Obviously after that you have setted activity's layout
Related
I am generating documentation using KDoc/Dokka for an android library.
I have a custom view, which extends LinearLayout.
The problem is that LinearLayout contains hundreds of public methods. Dokka generates empty documentation for all of these methods, even though I did not use or override them in my own code.
This completely buries any of my own methods and makes the documentation near useless.
How can I prevent dokka from generating documentation for inherited methods?
Currently this is not supported, probably we will add some flag to turn it on/off.
You can follow this issue: https://github.com/Kotlin/dokka/issues/1501
From the answer by #andrzej-ratajczak the following can be used
pluginsMapConfiguration.set(
["org.jetbrains.dokka.base.DokkaBase": """{ "separateInheritedMembers": true}"""]
)
here an example of my own module
dokkaHtml {
moduleName = "${project.name}"
dokkaSourceSets {
configureEach {
// Suppress a package
perPackageOption {
// will match all packages and sub-packages
matchingRegex.set(".*\\.internal.*")
suppress.set(true)
}
// separate inherited members to avoid polluting our public API
// https://github.com/Kotlin/dokka/issues/1501
pluginsMapConfiguration.set(
["org.jetbrains.dokka.base.DokkaBase": """{ "separateInheritedMembers": true}"""]
)
}
}
}
I am updating an app that uses the databinding library. I've been going through the breaking changes one by one, and I'm currently stuck on trying to access the binding variables. It looks like the accessors are now annotated with #Nullable, which means I have to use safe calls or assert non-null (which makes the code pretty ugly). Is there another alternative? Is there some sort of databinding setting that lets me change the generated annotations to #NonNull?
Generated code:
public abstract void setVm(#Nullable GeneralSettingsViewModel vm);
#Nullable
public GeneralSettingsViewModel getVm() {
return mVm;
}
Somewhere in code:
//now I have to do this
binding.vm?.observeOrientation()
?.subscribe()
?.addTo(subscriptions)
Considering the following structure:
public class WaterWorld implements IWorld {
...
#Inject
CreationMode creationMode;
#Override
public final void init() {
WorldModule.getComponent().inject(this);
}
...
}
Is it possible for WaterWorld to get dependencies if the Component has following structure:
void inject(IWorld world);
I am getting null this way. However, if I try to do it in the following
void inject(WaterWorld world);
then it works. However, I have many classes implementing IWorld. I wanted to do it this way: void inject(IWorld world); How to do this or is there some other generic solution?
No, Dagger will always inject the class specified in the inject(Foo foo) method. It will inject objects in the parent types, but it will not inject objects in subclasses.
Dagger uses the type specified to generate code for the injection, but if you don't specify the specific class then Dagger simply doesn't know about it and won't inject its fields.
Note: You don't give any specific example, but it looks like you could be very well using constructor injection instead, which has no need for manual injection or inject methods in your component. If you have multiple implementations of the same interface you might even take a look at multi bindings with Dagger.
I stumbled across a very interesting Dependency Injection library called ButterKnife. Using ButterKnife it's easily possible to inject Views into activities or fragments.
class ExampleActivity extends Activity {
#InjectView(R.id.title) TextView title;
#InjectView(R.id.subtitle) TextView subtitle;
#InjectView(R.id.footer) TextView footer;
#Override public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple_activity);
ButterKnife.inject(this);
// TODO Use "injected" views...
}
}
However if using Dependency Injection those Views must be public so that Butterknife can inject it (using private fields results in an exception fields must not be private or static).
In my past project I always made all the member fields (including the views) private as I thought this is best practice (information hiding etc.) Now I am wondering if there is a reason why one should not make all the views public? In this case I cannot use ButterKnife but I want to use it because it simplifies the code a lot.
First off, Butter Knife is not a dependency injection library. You can think of it as a boilerplate reduction library since all it does is replace findViewById and various setXxxListener calls.
The reason that Butter Knife requires views not be private is that is actually generates code which sets the fields. The code that it generates lives in the same package as your class which is why the field must be package-private, protected, or public. If the field was private the generated code would fail to compile since it cannot access the private field.
The generated code looks something like this:
public static void inject(ExampleActivity target, ExampleActivity source) {
target.title = (TextView) source.findViewById(R.id.title);
target.subtitle = (TextView) source.findViewById(R.id.subtitle);
target.footer = (TextView) source.findViewById(R.id.footer);
}
When you call ButterKnife.inject(this) it looks up this generate class and calls the inject method with your instance of ExampleActivity as both the destination for the fields and the source for findViewById calls.
#SuppressWarnings("unsued")
#Override
#SuppressLint({ "InflateParams", "SimpleDateFormat" })
I don't get why we need to declare annotations.
We want to facilitate the writing and the maintenance of Android applications.
We believe that simple code with clear intents is the best way to achieve those goals.
Robert C. Martin wrote:
The ratio of time spent reading [code] versus writing is well over 10 to 1 [therefore] making it easy to read makes it easier to write.
While we all enjoy developing Android applications, we often wonder: Why do we always need to write the same code over and over? Why are our apps harder and harder to maintain? Context and Activity god objects, complexity of juggling with threads, hard to discover API, loads of anonymous listener classes, tons of unneeded casts... can't we improve that?
How?
Using Java annotations, developers can show their intent and let AndroidAnnotations generate the plumbing code at compile time.
Features
Dependency injection: inject views, extras, system services, resources, ...
Simplified threading model: annotate your methods so that they execute on the UI thread or on a background thread.
Event binding: annotate methods to handle events on views, no more ugly anonymous listener classes!
REST client: create a client interface, AndroidAnnotations generates the implementation.
No magic: As AndroidAnnotations generate subclasses at compile time, you can check the code to see how it works.
AndroidAnnotations provide those good things and even more for less than 50kb, without any runtime perf impact!
Is your Android code easy to write, read, and maintain?
Look at that:
#EActivity(R.layout.translate) // Sets content view to R.layout.translate
public class TranslateActivity extends Activity {
#ViewById // Injects R.id.textInput
EditText textInput;
#ViewById(R.id.myTextView) // Injects R.id.myTextView
TextView result;
#AnimationRes // Injects android.R.anim.fade_in
Animation fadeIn;
#Click // When R.id.doTranslate button is clicked
void doTranslate() {
translateInBackground(textInput.getText().toString());
}
#Background // Executed in a background thread
void translateInBackground(String textToTranslate) {
String translatedText = callGoogleTranslate(textToTranslate);
showResult(translatedText);
}
#UiThread // Executed in the ui thread
void showResult(String translatedText) {
result.setText(translatedText);
result.startAnimation(fadeIn);
}
// [...]
}
Java annotations bind specific conditions to be satisfied with code. Consider a scenario where we think we are overriding a method from anther class and we implemented code that (we think) is overriding the method. But if we somehow missed to exactly override one (e.g. we misspelled name. In superclass it was "mMethodOverridden" and we typed "mMethodoverridden"). The method will still compile and execute but it will not be doing what it should do.
So #Override is our way of telling Java to let us know if we are doing right thing. If we annotate a method with #override and it is not overriding anything, compiler will give us an error.
Other annotations work in a very similar way.
For more information, read docs Lesson: annotations
Annotations are basically syntactic metadata that can be added to Java source code.Classes, methods, variables, parameters and packages may be annotated .
Metadata is data about data
Why Were Annotations Introduced?
Prior to annotation (and even after) XML were extensively used for metadata and somehow a particular set of Application Developers and Architects thought XML maintenance was getting troublesome. They wanted something which could be coupled closely with code instead of XML which is very loosely coupled (in some cases almost separate) from code. If you google “XML vs. annotations”, you will find a lot of interesting debates. Interesting point is XML configurations were introduced to separate configuration from code. Last two statements might create a doubt in your mind that these two are creating a cycle, but both have their pros and cons.
For eg:
#Override
It instructs the compiler to check parent classes for matching methods.