Are there any cons when using view binding rather than findViewById? - android

Since I discovered the use of view binding by enabling
buildFeatures {
viewBinding true
}
in my gradle file, I never used findviewById in my code again. I wonder now if there is a cons to doing things this way.
If this is the best method, why does android studio not enable this option by default when creating a new project? If not, when should I avoid using view binding? thank you.

Once you enable it for a project, view binding will generate a binding class for all of your layouts. That's the only "con" I see, it just generates more code, so it would increase the size of the project, compile time, etc. While it won't be a huge difference for projects with very little layouts, it could change significantly for larger projects.
Here's a very interesting read about ViewBinding performance : https://blog.stylingandroid.com/view-binding-performance/

Related

Why the ids are removed?

In my Android project I use the view binding:
buildFeatures {
dataBinding = true
viewBinding = true
}
Ideally I would only use the dataBinding, but in this case I always need to use the tag
<layout ...> </layout>
in XML layouts to get it used. That's why I only use that where I really need to bind data within XML. In other cases I use viewBinding since the plugin 'kotlin-android-extensions' has been deprecated. Everything is ok, but the following issue occurs when I run Analyze -> Inspect code. Once it's done and some unused resources are found (under Android -> Lint -> Perfomance -> Unused resources) and I remove all of them since I do not need them, it also removes the assigned IDs to all views in XML's. However, the IDs in XMLs with tag <layout ...> </layout> are not removed. The IDs are removed only in case of use viewBinding.
I am not expert, but I think, removing unused resources does not have anything to do with IDs of Views and that shouldn't happen.
After each optimization (meaning cleaning project from unused resources) I always have to assign the IDs which is very unproductive, especially when the project gets bigger and there are much more Views with IDs.
Why does it happen and how can I prevent that?
This might be happening because lint doesn't know that you will use those IDs in view binding... which is wrongs it should know. What you can do is when you run the lint to find unused resources there is an option you can uncheck which doesn't remove the unused IDs.
.

Android viewBinding is not binded some views in layout

I have a problem with viewBinding. I use buildTools 28.0.3 and Android Studio 4.1.2
I have a layout with more than 50+ views. The binding class is generated normally but there are around 40 views that has been generated. I cannot figure out why the rest views are not generated. They are the same view's type as the generated views.
Anybody face this issue before?
I found the cause of this issue. It's because I include "&" in layout file (even I put them in comment secion). I remove that character and re-build then everything is good.

Is there anything butterknife can do that databinding can't?

we're just starting a new project
And it seems like both butterknife and databinding are awesome tools to reduce boilerplate code.
We started with butterkife and added databinding later, the idea is to not have viewmodel classes in java instead express them in xml.
Is there any reason to keep butterkife around ?
The same situation happened in my current project. We used ButterKnife and DataBinding alongside. We decided to get rid of one of those as we used ButterKnife version 7.X (converting to 8.X would be quite painful in such a big app). We got much cleaner code with DataBinding and removing the other library reduced build time :)
BUT notice that DataBinding still won't work with enabled Jack&Jill compiler, which will change soon hopefully. Using neenbedankt-apt and Retrolambda is still OK.
TL;DR
Get rid of ButterKnife.
Butter Knife come with bind resource like color, animation,...etc.
that data binding can't do actually.
For a small XML view Data binding is good but as your view will become complex then it really hard to maintain it.
Please check the below link
https://medium.com/#Miqubel/4-reasons-im-not-using-android-data-binding-e62127c2650c

Performance in XML layout vs layout in code?

Is there any performance difference between layouts done in code vs XML layouts in android?
Yes. XML layouts need to be loaded, parsed and inflated to generate the View. Behind the scenes the LayoutInflater does exactly what you would do when writing layouts through code, but with the overhead mentioned before.
Here is an interesting article on this topic, which covers View generation through code, also it is about a library written in Kotlin: https://nethergrim.github.io/performance/2016/04/16/anko.html
But even though there is a performance win, I would not recommend to write layout in code for the following reasons.
You couple your layout and your business logic. That's always bad.
You can't use the features of the AppCompatDelegate (loading Views for the latest Androind version. E.g. an AppCompatButton instead of a normal Button.
As far as i know, i can make one difference. Please correct/enhance my answer if possible.
For XML based, In compile time, the ID generated and stored in R file which we use to refer to that any particular layout(like TextView, Button etc.) inside our code. As the reference ID is getting generated at compile time, so at run time this overhead is not there and it is faster.
In code based, all things done at run time which makes the app slow. It is not that much visible if small number of layouts are there. But if you are creating a lot of Layouts pro-grammatically, then you may realise the slowness in your app.
Its hard to imagine that using XML would ever be faster.
Android SDK has a lot of performance tweaks to make loading and parsing XML fast. in recent times, if you use data binding to replace findViewById this dramatically improves performance as well as each call to findViewById parses the XML tree. Where as databasing will only parse the tree once.
Also, using include in XML allows for reuse of Views which improves performance especially in cases where you would have large object churn. There is all sorts of I eternal caching and pooling of objects as well so it's possible that inflated objects are cached/pooled and cloned for subsequent use reducing the overhead on using XML. I know this is definitely the case for Drawable assets hence the need to call mutate if you ever plan on modifying one.
There are scenarios where code would be slower, with every View you create and add to your layout, you will trigger a measure and layout pass, so if you try to build a complex, deep nested layout using code at runtime, this would take a lot longer to load.
There are other factors to consider, like:
styling is hard if not impossible to apply at runtime.
code with views created complete runtime mY be complex, hard to maintain and bug prone.
You can use ConstraintsLayout to flatten your views hence avoid writing custom ViewGroups if performance is an issue.
XML allows use of the editor to preview and debug your layouts.
If the ViewGroup you want to create is simple, or simply want to create a single View and insert it into a ViewGroup, doing it in code is probably hard to beat by any criteria.
If you want to do something a lot more complex, using XML and all its features like ViewStub, includes, DataBinding is probably the way to go. I have noticed that inflating Views can be visibly slow, if you do it a lot, hence the ViewHolder pattern, but if you're careful, it's hard to justify ever building Views and ViewGroups in code for any thing but simple layout additions.

Proper configuration change handling

I'm writing a cross-platform app for iOS and Android using MvvmCross.
The Android version makes use of nested Fragments. For example, the home view is a navigation drawer, its various navigation hub views are Fragments which may be split views containing other fragments, and on top of that, each view may show a dialog fragment as well.
Additionally, not all ViewModels are shown via ShowViewModel(), some of them are used more like PropertyChanged event providers as demonstrated in the N=32 video.
This is working fine until a configuration change takes place (typically, rotating the device). When the fragment views get recreated, their View Models aren't and are set to null. This is hinted at in the following MvvmCross issue #636, where Stuart also mentions he'd like the project to come up with some best practice advice.
My question now is what are the best practices for this? What do you do if you have to properly support Android configuration changes in MvvmCross?
I've tried working around the problem as outlined in the issue linked above, i.e. by some form of ViewModel registry in the parent ViewModels, and also by trying to serialize the Fragment's ViewModel when saving its instance state, with limited success. The results felt hackish at best. The problem remains that a Fragment doesn't know how to recreate its View Model in MvvmCross. Oh, and disabling configuration changes on device rotation doesn't count as an answer. ;-)
Obviously this answer is not a direct answer to your question but I feel its related enough to mention here.
In my android apps I have started to inject a Controller (or MVA style Adapter) into a View / Fragment / Activity using the Dagger Dependency Injection library. This has the crucial property of maintaining the instance of the Controller class, so on rotation / config change the same Controller is re-injected.
It seems that Mvx.Resolve() should be able to perform this ideally, or your gonna have a bad time. If it does not introducing a middle layer cache between your view classes and the Mvx class seems the only option to me. But this is my first hour or so reading about Xamarin so I may be off the mark. I have been an Android dev for 5 years now though so just thought I would add my 2 pence :)

Categories

Resources