anvil icon indicating copy to clipboard operation
anvil copied to clipboard

View factories

Open leonrd opened this issue 8 years ago • 3 comments
trafficstars

What this PR does:

  • Adds ability to instantiate views using a factory function, instead of using constructor reflection. This should also provide a bit more type safety. This is similar to how Anko works with { ctx -> View(ctx) }
  • Anvilgen now creates lazy factory functions for the above functionality.
  • Anvilgen will skip creation of abstract views, but still generates attrs for them. This is a side-effect of the above type safety: could not instantiate abstract views.
  • Anvilgen will skip creation of views which do not have constructor(Context). This is a side-effect of the above type safety: could not properly instantiate these views. In the past, constructor.newInstance(context) could have failed.

I haven't made any benchmarks yet, but I think this should provide some performance improvements versus viewClass.getConstructor(Context.class).newInstance(c);

Besides this, in Kotlin you get a rather nice syntax with v(MyCustomView(it)).

The only issue with this approach, that I could see, is that these functions should be cached, otherwise Anvil will reinstantiate the view on every render. Which is a pretty big deal.

Fortunately, Retrolambda and Kotlin caches lambdas, so this should work fine: v((ctx) -> { new MyCustomView(ctx) }) and this v({ ctx -> MyCustomView(ctx) }) and this v({ MyCustomView(it) })

Kotlin (and maybe Retrolambda, didn't check), on the other hand, does not cache method references. So while this is a pretty nice syntax: v(::MyCustomView) { /* do something */ } the problem is that it would instantiate the view on every render.

Any thoughts?

leonrd avatar Jan 14 '17 11:01 leonrd

Fortunately, Retrolambda and Kotlin caches lambdas

Not sure where did this came from, but it is not true. If we'll call the factory function twice it will return a new object on each call (no matter if it's Kotlin, Retrolambda or Java 8)

dmitry-zaitsev avatar Feb 04 '17 18:02 dmitry-zaitsev

Sorry for the confusion, I wasn't refering to that. What I meant was: kotlin, and possibly retrolambda, reuses the reference for a given lambda. So you can compare and see if the factory function changed.

leonrd avatar Feb 04 '17 18:02 leonrd

Oh OK, now I get it - thanks for the explanation.

Some other feedback - code indentation is slightly off for some files (like Anvil.java).

dmitry-zaitsev avatar Feb 04 '17 19:02 dmitry-zaitsev