Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative view listener injection #7

Closed
zserge opened this issue Mar 28, 2015 · 4 comments
Closed

Alternative view listener injection #7

zserge opened this issue Mar 28, 2015 · 4 comments

Comments

@zserge
Copy link
Collaborator

zserge commented Mar 28, 2015

Currently, the easiest form of binding a view listener is to use Java 8 closures:

v(Button.class,
  onClick(v => doSomething()));

This is compact and clean, but it creates a new onClickListener object each time. Of course one can write listeners inside a Renderable class, but that becomes somewhat bloated:

View.OnClickListener onButtonClicked  = (v) => doSomething();
...
v(Button.class,
  onClick(onButtonClicked));

I'm looking for some lightweight approach to use Renderable methods instead, e.g:

public void onButtonClicked(View v) {
  doSomething();
}
...
v(Button.class,
  onClick(???)); // refer to onButtonClicked somehow

The first thing coming to my mind is and event bus. An event instance will be passed into a view node, then the real listener bound by Anvil will submit that event instance to the event bus and the Renderable (or any other class) would handle it.

public void onEvent(ButtonClicked e) {
  doSomething();
}
...
v(Button.class,
  onClick(new ButtonClicked()));

Event objects are lightweight, which is great. I just worry about a massive amount of various event classes for each listener for each view. Any ideas?

@zserge
Copy link
Collaborator Author

zserge commented Apr 7, 2015

Using events emitted inside the view listeners will bring the Flux architecture to Android.
That will be uni-directional data flow, views will emit events (Actions in Flux), Stores will subscribe to those actions and will perform the business login. One the action is handled and store has changed its state - it will call render() method to update the views.

Flexible architecture, explicit update path, immutable data and all other benefits of Flux.

@meoyawn
Copy link

meoyawn commented May 2, 2015

don't you want to separate flux approach from just the rendering/UI events handling?

I think spawning the event object is exactly the same as spawning the OnClickListener, GC-wise

@zserge
Copy link
Collaborator Author

zserge commented May 2, 2015

@adelnizamutdinov Correct, Anvil core doesn't provide any of the UI listener bindings at all, but it allows binding in general. Then Attrs.java provide most common listener bindings like OnClickListener, which is good if you have lambdas or if you write in Kotlin, but in Java 6 it can be a pain. I was looking for some method to bind class methods easily in Java 6, because now one has either:

View.OnClickListener mListener = new View.OnClickListener() {
  public void onClick(View v) {
    // Code here
  }
};
v(SomeView.class, onClick(mListener)); // Good thing - zero garbage

or

v(SomeView.class, onClick(new View.OnClickListener() {
  public void onClick(View v) {
    // Code here
  }
});

I like neither.

I agree that events are no lighter than this simple click listener, but maybe some event factory could be used to not instantiate new objects, but reuse the existing ones (one per binding).

Anyway, to me code lightness is more important here than the execution speed or GC.

@zserge
Copy link
Collaborator Author

zserge commented Sep 30, 2015

I decided to not include this kind of functionality.
Most modern developers use Java 8 or Kotlin, so they can use method pointers or lambdas. I did the benchmarks, lambdas are very cheap, compilers often optimize them to be singletons. So no need to add events as the first-class citizens to Anvil.

Of course one might want to write a library on top of Anvil if he find this useful.

@zserge zserge closed this as completed Sep 30, 2015
Mishkun pushed a commit to sgrekov/anvil that referenced this issue Sep 2, 2019
* add sample app module to project

* update travis config

* move buildscript section to parent
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants