Are there reasons not to use DataBindingUtil.inflate? - android-databinding

When binding a fragment to a layout the two most common ways (AFAIK) to do it is to:
FragmentMyexampleBinding binding = FragmentMyExampleBinding.inflate(inflater, container, false)
or
FragmentMyexampleBinding binding = DataBindingUtil.inflate(inflater, R.layout.fragment_my_example, container, false)
So my question is, what's the advantage of doing it the first way other than the statement being shorter?
Using DataBindingUtil and passing in a layout file lets Android Studio know which layout file is related and generate a shortcut icon to the layout file, and it also allows Android Studio to quickly find all reference to the layout file if you should ever want to rename it. Is there any reason not to do this?

The documentation for DataBindingUtil.inflate says this
Use this version only if layoutId is unknown in advance. Otherwise,
use the generated Binding's inflate method to ensure type-safe
inflation.
So the major advantage of the FragmentMyExampleBinding.inflate is the fact that you're guaranteed type safety. The DataBindingUtil.inflate method has to do some under the hood "hocus pocus" at run-time to figure out what type to return, and there's a chance that something goes wrong.
So in conclusion while there isn't any reason to not use DataBindingUtil.inflate there's at least one reason to use FragmentMyExampleBinding.inflate over DataBindingUtil.inflate whenever you can

Related

IntelliJ type error when using Geb static content DSL with parameters

Whenever I use a static-content defined closure that takes parameters, IntelliJ will complain that the types do not match (even if I specify the type inside the closure).
For example, if I use this static content block:
static content = {
myModule { $('myModule').module(CustomModule) }
namedModule { String name -> $(".$name").module(CustomModule) }
}
Both of the above items can be used successfully in my tests, but if I was to use 'namedModule' in one of my tests as follows:
page.namedModule("moduleName").moduleMethod("blah blah blah")
IntelliJ will highlight the parameter "moduleName" in yellow with the error:
'namedModule' cannot be applied to '(java.lang.String)'
We are trying to refactor our tests in a way that means you can navigate through the code easier (e.g. avoiding any Geb/Groovy 'magic' that IntelliJ can't resolve), and this is one of the last remaining issues preventing this from being possible.
This is a known limitation to Geb support in IntelliJ. IntelliJ always treats content definitions as properties of pages and modules even though they can be parametrised. Given that Geb support in IntelliJ is open sourced we could probably add support for this.
In the mean time, as a workaround you can use methods for parametrised content instead of content definitions and IntelliJ will be able to understand these and be able to refactor them:
void namedModule(String name) {
$(".$name").module(CustomModule)
}
There are some caveats, though:
you will loose ability to use content definition options; if you need to use these for a content definition then I suggest creating a parameterised "private" content definition (for example with a _ at the beginning of the name) that you will only ever access from within the page or module
RequiredPageContentNotPresent will not be thrown even if the returned content is empty; to work around it you will either need to add manual verification to each such method or use a strategy outlined in the first bullet point with using "private" content definitions

#NotNull, #Nonnull etc. all don't work in IntelliJ IDEA

I have tried annotating a field with
org.checkerframework.checker.nullness.qual.NonNull
org.jetbrains.annotations.NotNull
javax.annotation.Nonnull
And in all cases, assigning a null to it generates no complaints from IntelliJ 2016.2.
public class GreetingController {
#NotNull Integer x = 3;
public void foo() { x = null; }
}
That all compiles fine according to IntelliJ.
This page from IntelliJ specifically states that "IntelliJ IDEA highlights the problems “on-the-fly”, so you can see the inspection results right in the editor." I have even copied the example code (public class TestNullable) into my editor and it produces no errors.
This other page from IntelliJ states you can change the annotations it responds to. So I chose javax.annotation.Nonnull and made sure that was the one I was using in my code, still no luck.
To be clear, what I'm hoping for, and what I understand should be provided, is that the editor window / compiler alerts me to the problem (I am not looking for a runtime check, NullPointerException already works fine at runtime.)
In case it didn't work in real time, I tried "Rebuild Project".
I'm sure this must work, what am I doing wrong?
I have uploaded an example of this not working here: ZIP download.
As I can see from your screenshots and the sample project, IntelliJ IDEA does show you the warnings. Note that these warnings are shown by the code inspections which are running on the fly and will be displayed in the editor or in the Analyze | Inspect Code results. These warnings will not be displayed by the compiler.
Note that you can configure the warnings highlighting if needed (for example add the underwave effect):
You can also change the severity of the inspection (like to Error):
You may also want to vote for this feature request:
IDEA-78625 Provide inspection severity level that will work like validation and abort compilation
As a bonus, pay attention to the javax.annotation.Nullable annotation, it may be not what you think it's for, see this comment and the documentation. For some years IntelliJ IDEA has incorrectly suggested to use this annotation, while the correct one for such cases would be javax.annotation.CheckForNull:
This annotation is useful mostly for overriding a Nonnull annotation.
Static analysis tools should generally treat the annotated items as
though they had no annotation, unless they are configured to minimize
false negatives. Use CheckForNull to indicate that the element value
should always be checked for a null value.
"Settings" > "Inspections" > "Probable Bugs" > "Constant conditions & exceptions"
Tick the first option: "Suggest #NotNull annotation for methods that possibly return null and report nullable values passed to non-annotated parameters.
Click "Configure Annotations". By default, Intellij will use their own annotations from org.jetbrains.annotation. I was using the more general (my own opinion) annotations from javax.annotation.
I set Nullable to: javax.annotation.Nullable
I set NotNUll to : javax.annotation.NotNull
In order to set these new options, you must click them, then click the tiny checkmark button to the right to set it. Selecting the javax.annotation annotations then hitting "OK" will NOT lock in the new settings, you must use the checkbox button.
After successfully specifying javax.annotation.Nullable and javax.annotation.NotNull, the code correctly highlighted null problems.
The best that this can do is offer up warnings. It will not stop compilation from happening, since the annotations do not prohibit or preclude code compilation from taking place.
Be sure that you have the appropriate inspections enabled in your IDE, and be sure that you remain aware of what parameters you're passing into your method. The IDE can at best warn you, but it can't really stop you.
Alternatively, introduce a unit test to fail if that method receives a null parameter, and rely on that to ensure that you're not breaking code or expectations.

What 'expression:' property in QML Item

I've inherited a collection of mostly undocumented QML code. I'm new to QML, and I'm struggling to understand this code. In particular, the construct
expression: "connected == false"
occurs frequently in various items, but I can't find any documentation on what this property does. It does not seem to be defined anywhere in the existing code collection, so I'm assuming it's part of QML, but I'm having no luck turning it up anywhere.
It looks as though all items using this construct are backed by C++ classes. However, "expression" is not defined as a QPROPERTY anywhere in the C++ code.
Nope, there's no such property in QML. You'll have to look into the QML file for the type that it's used in, or the C++ if it's declared there.

titanium how do i add a view to the single context

So i have a titanium app, and i just read about single contexts. (Incidentally, somebody here should write a book about programming in titanium... the only one out there doesn't really mention single contexts or any of that new-fangled stuff. Heck, make it an eBook. I'd buy it)
The titanium documentation stresses their use (http://docs.appcelerator.com/titanium/latest/#!/guide/Coding_Strategies-section-29004891_CodingStrategies-Executioncontexts) and then politely forgets how to implement a single context!!
So, question:
Let's say i have the awesomeWidget page - this just shows a button, and when you click on a button a new screen appears.
The aswesomeWidget page is accessed through another page - it is not from the root of the titanium app.
Keeping to single contexts, how do i add the view that the button creates to the current window?
Do I:
keep a global pointer to the current (and only) window?
pass the variable holding the current window down to all the following pages that use it
something else?
First off, Titanium keeps a reference to your current window anyway for you, so this use case is easy. For example:
awesomeWidgetButton.addEventListener('click' function(e) {
var yourView = Ti.UI.createView({...});
Titanium.UI.currentWindow.add(yourView);
});
If you want to dig further, the concept of a single context is closely tied to the use of CommonJS modules and the require keyword. It is very simple to keep a single context, just never open a window with the url component filled out, and liberally use the require() keyword. Other than that, its up to your imagination to keep track of who points to what and vice versa, there are standard patterns and best practices that apply here (MVC, Singletons, just keep it simple) just as in coding in any other language.

Are the contents of a fragment visible outside the host plugin?

I have never worked with plug-in fragments before. I thought that by creating a new class within a fragment and exporting the package that contains it in the fragment's manifest, I'd be able to access that class from another plug-in that already has a dependency on the host plug-in. However, I cannot seem to make this work. Are the contents of a fragment ever visible to any plug-in besides the host plug-in? If so, is there something special I have to do to allow this?
The problem is not, that the contents of the fragment aren't visible to another plugin: They are - just try loading e.g. a properties file from the classpath, it still works if that properties file is provided by the fragment.
But what you don't have, is compile-time information about the fragment's contents. That's the principle of a fragment: You can't have a dependency on it. And you don't know, if somebody has fragments installed or not.
It's also not only a problem that just "any plug-in besides the host plug-in" has. It's a problem, that even the host-plugin itself has. It doesn't know about the fragment's existence at compile-time.
You also can't reliably use a fragment to override parts of the host plug-in's classes: FAQ Can fragments be used to patch a plug-in? , if that's what you want to do. The page also describes, how it can be done.
Hope this helps.