HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Android Global Variable Setup

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
globalvariablesetupandroid

Problem

I am using the Android library Retrofit for networking in my app. The library calls for creating a RestAdapter for making service calls. I want to use this same instance of the RestAdapter for all of my service calls. How is my setup for this scenario?

Extending Application:

public class CustomApplication extends Application {
    private RestClient restClient = null;

    public RestClient getRestClient() {
        return restClient;
    }

    public void initRestClient() {
        if (restClient == null) {
            restClient = new RestAdapter.Builder().setEndpoint(BASE_URL).build().create(RestClient.class);
        }
    }
}


Initializing instance and making sure I have access to the instance in all my Activities, without explicitly having to get it for each Activity:

public class BaseActivity extends Activity {
    protected RestClient restClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ((CustomApplication) this.getApplication()).initRestClient();
        restClient = ((CustomApplication) this.getApplication()).getRestClient();
    }
}


Then all my Activities will extend BaseActivity.

Solution

I agree with both @mjolka and @kyle-falconer. In fact the two points are very similar, because dependency injection frameworks usually work by giving you singletons by default. Mjolka's suggestion of adopting Dagger will be good long-term solution and definitely worth the time investment. Kyle's suggestion is more of a direct, simple solution you can implement right now.

If you go with Kyle's approach, I would point out the modern way of implementing singletons in Java using an enum, that's simpler and more robust:

enum SingletonRestClient {
    INSTANCE;

    private final RestClient restClient;

    private SingletonRestClient() {
        restClient = new RestAdapter.Builder().setEndpoint(BASE_URL).build().create(RestClient.class);
    }

    public RestClient getRestClient() {
        return restClient;
    }
}


You could use this in an activity like this:

public class SomeActivity extends Activity {
    private RestClient restClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        restClient = SingletonRestClient.INSTANCE.getRestClient();
    }
}


Of course, you will have to do this in all your activities that need the rest client.
But this is still better than forcing all your activities to extend a base activity.

Don't use inheritance just to share data.
The right reason to use inheritance is when there is an is-a relationship.
Can you say that SomeActivity is a BaseActivity?
This sounds inevitably wrong, because the very nature of a "base activity" is that there is just one such activity.
A good example would be an EmployeeActivity inheriting from a PersonActivity,
which could make sense, since an employee really is a person.

We don't have more details about your context.
If there is no is-a relationship between the classes involved,
then don't use inheritance, and prefer composition instead:
let each class that needs a rest client get it from the singleton.

Code Snippets

enum SingletonRestClient {
    INSTANCE;

    private final RestClient restClient;

    private SingletonRestClient() {
        restClient = new RestAdapter.Builder().setEndpoint(BASE_URL).build().create(RestClient.class);
    }

    public RestClient getRestClient() {
        return restClient;
    }
}
public class SomeActivity extends Activity {
    private RestClient restClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        restClient = SingletonRestClient.INSTANCE.getRestClient();
    }
}

Context

StackExchange Code Review Q#67079, answer score: 6

Revisions (0)

No revisions yet.