Where to declare functions which are used in every activity?

Viewed 299

I call a function in onCreate function of an Activity to refactor my code. I wonder where to declare this function that is potentially used in every Activity of my app.

What I have done (it works fine) is to create a function class with a companion object where all my global functions are declared. But my question is: Is it a good way to do like that?

5 Answers

You can create some BaseActivity or YourAppNameActivity and call your function inside its onCreate. Then, every activity that extends BaseActivity as usually will call super.onCreate() and therefore the code you need

As long you do not have shared (mutable) state (as it can lead to side effects, there is nothing wrong in placing common code into companion object.

You can have a BaseActivity you extend your Activities from, but I would try to avoid inheritance in favor of composition.

I call a function in onCreate function of an activity to factor my code. I wonder where to declare this function that is potentially used in every activity of my app.

I would create a BaseActivity and let all your Activities inherit from it.

abstract class BaseActivity : AppCompatActivity() {
    private fun init() {
        // your code
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        init()
    }
}

In case your init function does not depend on anything which comes from the subclass, you can just invoke it in onCreate each time (as shown above), otherwise make it protected and call it from the subclass (with parameters).

What I have done (it works fine) is to create a Function class with a companion object where all my global functions are declared. But my question is : is it a good way to do like that ?

It depends on if you need global shared state or not. In the first case using an object or a companion object would not be a bad idea.

If you don't need global state, or what to pass in whatever state to the utility function itself, a top level function would be sufficient.

Utils.kt

fun someUtilityFunction(foo: Int) {
    // ...
}

It's a good practice to move all that common code to a parent class and make each activiy heredate that parent class, by the way creating a companion object its a good option only if you want to create a singleton, a singleton it's needed when you want to instance that object only once.

For example a function in baseActivity (parent class) to create an intent filter or add code to onCreate function

public class BaseActivity extends Activity {
public static final String FINISH_ALL_ACTIVITIES = "somecode";
public final IntentFilter INTENT_FILTER = createIntentFilter();
private boolean _started;

private IntentFilter createIntentFilter() {
    IntentFilter filter = new IntentFilter();
    filter.addAction(FINISH_ALL_ACTIVITIES_ACTIVITY);
    return filter;
}

// region Blindaje de eventos ciclo de vida
@Override
protected void onCreate(Bundle savedInstanceState) {
    // inside your activity (if you did not enable transitions in your theme)
    getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS);
    super.onCreate(savedInstanceState);
    try {
        doOnPostCreate(savedInstanceState);
    } catch (Throwable t) {
        doOnErrorNoControlado(t);
    }
}

If your method is touching the activity's view then BaseActivity approach would be fine. But if it doesn't move it to some singleton ActivityHelper class.

Like said, BaseActivity approach (inheritance) comes with a cost. You should be able to make good design choices by not putting everything inside it which will eventually makes it more coupled.

Follow composition pattern only if you find your code is interfering with its lifecycle. There are a few registerLifecycle callbacks for activity or fragment that can help you.

Related