• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps A class for each runnable?

hansschmucker

Android Enthusiast
OK, I must be doing something wrong here, due to my limited experience with Java, but it's hard to describe the problem in few enough words to feed it into Google:

My Renderer is receiving events from the main thread using queueEvent(Runnable) . I know I can declare those inline using new Runnable(){...}, but what I can't do is include any variables available while the Runnable is created. I expected something like this to work:

Code:
        view.queueEvent(new Runnable(currentRenderer,currentSig){
            private int sig;
            private GameRenderer rnd;
            public Runable(GameRenderer aRnd, int aSig){
                sig=aSig;
                rnd=aRnd;
            }
            @Override
            public void run() {
                rnd.perform(sig);
            }
        });

or maybe

Code:
        view.queueEvent(new Runnable(){
            private int sig=currentSig;
            private GameRenderer rnd=currentRenderer;
            @Override
            public void run() {
                rnd.perform(sig);
            }
        });

But no such luck. For now I've created a separate class for each event runnable, but frankly this is tiresome and counter-intuitive, no to mention that it clutters up my src directory something fierce: Does any long-time Java expert know how this is supposed to be solved?
 
Thanks very much... I simply didn't know what to look for, coming from JS the word the keyword there would be "closures", but that doesn't fit the Java way of doing things. Again: thank you.
 
Feel free to pm a mod or guide if you need a thread moved :)

Anywho, what OneSide is describing is called an InnerClass and generally it's actually an antipattern. But it's still good to know and has some uses.

The two methods of object creation inside a param of a method that you you have above are (in my very opinionated opinion) one of the worst things about javascript and the techniques people use with it.

To me, readability is paramount, and anonymous inner classes (declaring it within a method call) is terrible for readability and modularity.

I don't know what specific hurdle you are trying to overcome, but if you can, separating out something to it's own class is usually a good thing. Especially if you can make it so that it's "dynamic" and loosely coupled.

Since you came from javascript which is largely procedural and function based you may want to learn a bit more about some coding theory. While being a javascript programmer takes no less talent, there are different approaches to class-based, strongly type languages with inheritance vs dynamicly typed prototype based inheritance. And dont get me wrong javascript has some cool advantages by being dynamic (lazy evaluations, etc). Some coders swear by these dynamic/prototype languages. Nevertheless there are some concepts a lot of JS programmers dont learn as they dont apply to JS.

A few things thing definitely worth trying to learn:

- OOP best practices
- When to use an Interface or instead Extend a class (Inheritance) or write Abstract methods (Inheritance)
- Polymorphism
- Ecapsulation
- Cohesion
- Coupling
- Separation of concerns
- Design Patterns

And since Java is multithreaded: Concurency/locks/synchronization/dead locks.


Sorry if that's a little too much advice/opinion for one post, but I feel like I know where you are coming from as I used to be an ActionScript programmer for 10 years or so. And my knowledge grew with the language.

While AS1 was almost identical to JavaScript, AS2 introducted classes and strong typing, and AS3 introduced complex Event Dispacting and was closer to C# or Java than it was to JavaScript.

So I feel like I have had the same growing pains, so just trying to relay what I went through :)

OK time to stop babling and get back to my coding :) Cheers
 
I'm actually coming from C... well, originally BASIC (GFA Basic), but C as the first commonly used language and learned C++, Java and C# in university, but Javascript is the language I'm most comfortable with. I don't necessarily mean JS as it's implemented in the browser, I'm frequently working with command-line only and Gecko Chrome classes.

So I've encountered all of this before, it's just the specifics that sometimes slip my mind (which language allows getters/setters, which allows inner classes, are inline function declarations possible, ...)

But I think you might really have a good time reading up on JS, because all the concepts are available there too, you just have to remember using them :) . I often write pure OOP Javascript, I love inheritance, you'll usually find interfaces all over my code and there's rarely a method that I haven't overloaded.

The thing that I love about JS is that I MAY apply any of these concepts if it fits, but I can entirely ignore it when it doesn't. Sometimes, especially if the program is small, OOP just creates unnecessary overhead, as does separating views.
 
Ah it's been a long time since I used JS -- it seems it may have progressed quite a bit.

Still, inner classes and inline/anon functions are anti-patterns imho :) Party due to my subjective style, but partly backed up by CS researchers.

That's not to say I never use them. I have one class with something like 8 inner Thread classes and god knows how many runnables and listeners and a handler and a receiver... and a kitchen sink (it's long overdue for a refactor)


Here's a helpful tip though when you do use them:

http://developer.android.com/guide/practices/design/performance.html#package_inner


.
 
That's one of the things that absolutely scream "inline something"... when it goes across thread boundaries, you're often forced to encapsulate something that wouldn't be in its own class or even method.

As for JS. It hasn't really progressed... well it did that too, but that's not what I'm talking about. JS has had the basic building blocks needed for all this since the first ECMA version. Turns out that the only things you need for Java-style inheritance are closures and prototypes. Take this as an example (I've embedded the script in a HTML document so you can try it). Look at the first script element. What's in there is certainly not pretty, but this is the equivalent of a standard library on C. You don't have to understand it (although I can explain it to you if you want to ;) ), but it provides important functions, in this case a method that lets one class inherit from another and one that wraps a function into the equivalent of a Java method. That allows the code in the second block behave almost like Java (BTW, the second try/catch is supposed to throw)... and that's what I love about JS: Everything is transparent and by definition fixable. If you don't like how something works, you don't have to rebuild the browser, the equivalent of a lib is enough.

Code:
<!DOCTYPE html>
<html>
    <head>
        <title>JS Classes</title>
        <script>
            Function.prototype.inherit=function(parent){
               var proxy=function(){};
               proxy.prototype=parent.prototype;
               this.prototype=new proxy();
            };

            Function.prototype.bind=
                Function.prototype.bind
                || function(scope){
                    var func=this;
                    return function(){
                        return func.apply( scope, arguments);
                    };
                };
        </script>
        <script>
        
        
        
            var MessageCarrier=function(){
            };
            
            MessageCarrier.prototype._value="";
            MessageCarrier.prototype.setValue = function(/*string*/ message){
                this._value=message;
            };
            
            
            var MessageBox=function(){
            };
            
            MessageBox.inherit(MessageCarrier);
            MessageBox.prototype.show=function(){
                window.alert(this._value);
            };
            
            
            (function(){
                try{
                    var mb0 = new MessageBox();
                    mb0.setValue("Hello World");
                    mb0.show();
                }catch(e){
                    alert(e.toString());
                }
                
                try{
                    var mc0 = new MessageCarrier();
                    mc0.setValue("Hello World");
                    mc0.show();
                }catch(e){
                    alert(e.toString());
                }
            })();
            
        </script>
    </head>
    <body></body>
</html>
 
Yeah, that's an example of some of the weird things that prototype based languages can accomplish. Lazy evaluation and the like.

func.apply(...) is an advantage of having a function as a high order type too, no? ActionScript had this as well.


It's one of the things i miss most about AS. That and event dispatching. it was so much cleaner than 1000 custom listener objects or handlers that 500 lines long... :)
 
That's one of the things that absolutely scream "inline something"... when it goes across thread boundaries, you're often forced to encapsulate something that wouldn't be in its own class or even method.


See this part I dont follow though, (i get the JS code stuff :) )

Why does that scream to you inline?

To mean that screams "externalize and encapsulate"
 
Yes, functions as a data type are really the one thing I miss in many languages... someone coming from C and JS is more than a little irritated about all the hacks and overhead that are present in languages like Java to get around this limitation.

About inlining: Imagine that you have structured your code so that the thread is really equivalent to one class... there's a method that handles all events coming from other threads and this is really the only way that class interacts with the outside world. You want to send message codes to it, but most event systems found on Android only allow using runnables. So where you want to say myThread.sendMessage(MyThread.EVENT_CURSOR_MOVED); you instead have to pass a runnable. In JS you'd say myThread.sendMessage(function(){ this.processEvent(MyThread.EVENT_CURSOR_MOVED);}); , but since Java doesn't have such a compact way you instead have to create a totally unnecessary construct that does nothing but blow up your code, and unnecessarily inflating your source code is pretty much the worst thing you can do for readability.
 
I totally agree I love functions as a type. :) I dont mind runnables but I dont make use of them as much as I should.

You want to send message codes to it, but most event systems found on Android only allow using runnables. So where you want to say myThread.sendMessage(MyThread.EVENT_CURSOR_MOVED); you instead have to pass a runnable.


Anyways, I dont think I have ever come across this situation. What is the sendMessage method? Why would it only accept a runnable?

Are you thinking of Handlers?

Certainly a custom class extending Thread could have a public method for receiving messages... (you would have to worry about sync/deadlocks but that would be the case for both inner and separate classes)

And Handlers accept Objects as params, so you dont HAVE to send a runnable, though I gues you might want to at times.

This to me says "constant" too:

Code:
MyThread.EVENT_CURSOR_MOVED
interesting/informative converation btw :) cheers
 
Likewise :) . Like I said, I grew up on the HTML DOM, so to me any kind of message processing is an event-system, no matter if it's implemented as a message queue/loop pair, a separate thread or just a queue.... everything that takes a value and causes another function to run. GLSurfaceView::queueEvent (which only accepts Runnables), Handler::sendMessage and so on. Mainly I'm using queueEvent here, for communication from the main thread to the graphics thread, with a few sprinkles of Handler for the rare occasions when the data has to flow the other way around. Deadlocks are really not an issue unless you plan on re-using the object to send... the pointer is atomic, but even if it wasn't the message would only be dispatched when it is ready.

Every time I dispatch an event with queueEvent it currently looks like this:
Code:
menuRenderWidget.queueEvent(new FEventRunnable(menuRenderWidget.renderer,FEventRunnable.LOAD_LEVEL, level));
with FEventRunnable defined like this:
Code:
public class FEventRunnable implements Runnable {
    FRenderer renderer;
    int sig;
    Object val;
    public final static int LOAD_LEVEL=212;
(...)
    public FEventRunnable(FRenderer aRnd,int Asig, Object aVal){
        renderer=aRnd;
        sig=Asig;
        val=aVal;
    }
    @Override
    public void run() {
        try {
            renderer.onUserEvent(sig,val);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
And that's really what I object to: I have to construct a whole object for each call just to transport two values.
 
I just find this stuff more readable, although more verbose:

Code:
RunnableEvent myRunnableEvent = new FEventRunnable();

myRunnableEvent.renderer = menuRenderWidget.renderer;
myRunnableEvent.action = FEventRunnable.LOAD_LEVEL;
myRunnableEvent.level = level;


menuRenderWidget.queueEvent( myRunnableEvent );
Additionally, you could use a factory design pattern here to handle the object creation and make the runnable more flexible and decoupled.


Code:
Renderer render = menuRenderWidget.renderer;
int action = FEventRunnable.LOAD_LEVEL;
int level = level;

RunnableEvent myRunnableEvent = EventFactory.create(renderer, action, level);


menuRenderWidget.queueEvent( myRunnableEvent );
The thing I like about these strategies is that only one tiny small task is accomplished on each line. Like baby steps. Helps for debugging, and help make the code clear and obvious to someone who has never seen it before, or to someone who hasn't seen it in months/years.
 
Still means a whole object, but you're right... that code has somehow cropped up trying to find a way to make it work at all, but you're right, it really should be a factory.
 
Back
Top Bottom