Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java - Android - Split Activity/Class into multiple files for better organization (solution)

I'm not PRO in JAVA , but I found myself of getting crazy with Android activities getting too large.
After a few pages of code length I found myself of permanently scrolling back and forth!
Not only OnClickhandlers can grow huge, just a lot of code tends to sum up in a bigger activity.
Fragments were no solution for me.
In general Java does not allow to split up a class into several files so a hack is needed.

I browsed through a lot of stackoverflow threads regarding that, not one had a solution.
I solved it anyway, maybe this helps others.

This is a bit Android focused as I got anoyed by my huge onClick Handlers for all the menus and buttons but I guess it will work for other general Java problems as well the same way.

like image 931
John Avatar asked Dec 04 '14 01:12

John


2 Answers

A simple approach that I follow is to move the View concerns into a separate class (let's call it ViewManager) and make the Activity/Fragment work only as a controller.

A ViewManager is generally responsible for -

  • Inflating the layout
  • Getting references to all the views
  • Displaying data in the views
  • Handling click/touch events
  • Animations

The Activity/Fragment is only responsible for -

  • Fetching data and passing it to the ViewManager to display it
  • Handling navigation
  • Posting data to a server/DB

For UI controls that trigger an action that the controller is responsible for, say launching a new activity when a button is clicked, the ViewManager receives the click and calls a method in the controller that takes care of the navigation.

If you want to further eliminate boilerplate code (click handlers, findViewById() calls, etc), consider using libraries like ButterKnife.

like image 116
Mus Avatar answered Nov 08 '22 08:11

Mus


One solution is simple, you can make the main class fields public
However that will mess up your code, you should keep the fields private when possible. Aside from better code completion of your IDE it's also protecting the classes from illegal outside manipulation.

Now the trick for me was inner classes.
An inner class can access the private fields of it's parent, however Java does also not allow to put an inner class into another file.
It has to be defined INSIDE the parent class.
This is where I started to dig and found a solution which might be considered to be acceptible.
If this hurts java experts, I'd appreciate not to be downvoted ;)

The trick is to create an "abstract class" in an own java file.
I named it a bit outside conventions to make it stand out: InnerMainActivity_onClickHandlers.java
MainActivity is my main class (the parent of the new inner class)

In my Parentclass I have this field defined, a normal inner class but extending the new class:

private class inner extends InnerMainActivity_onClickHandlers{
    public inner(MainActivity mainActivity)
    {
        super(mainActivity);
    }
};

In my MainActivity.onCreate:

Button.setOnClickListener(new inner(this));

As you can see, as you can see it passes the MainActivity (Parent) to the Inner class.

Now the Inner class iteself:

public abstract class InnerMainActivity_onClickHandlers implements View.OnClickListener
{
    private final MainActivity main;

    public InnerMainActivity_onClickHandlers(MainActivity mainActivity)
    {
        this.main = mainActivity;
    }

    @Override
    public void onClick(View view)
    {
       // here implement the listener
    }
}

To make this work as advertised you need to change the private properties of your MainActivity/Parent to protected.
Now the extended inner class has access rights to the parent fields, however any external class can still not access it.

In this case I have a dedicated class for all onclick listeners, a second class could be used for other things.

like image 21
John Avatar answered Nov 08 '22 06:11

John