Skip to content Skip to sidebar Skip to footer

Why Aren't Getters Preferred When Accessing Variables Between Activities?

Daily there are many questions of the following type on SO: How do I get a variable from another Activity? The answers usually recommend to use SharedPreferences or Intent.putEx

Solution 1:

The answer to your question is two fold:

  • For the meta aspect, which belongs on meta SO anyway, many newbie programmers see Android, want to write apps, and suck at Java.
  • For the other quesiton, typically using a getter and setter won't work, because you can't pass objects between Activities in a straightforward way. While you can technically do this with a Parcelable, it's not recommended, and the better way is to use an intent to pass data between application components.
  • Another point this highlights is that Android apps should keep a minimal amount of state inside components. I think this has been a big success of Android. If you look at apps out there, there is on average a lot less global state than typical programs written in java. The programs are also smaller, which is to be expected, but the fact that an atomic activity can represent the state of a single screen, and the fact that any single screen won't typically be persisting that much state across the entire app, leads to an good logical separation between app components.

Solution 2:

The simple answer is because the Activity life cycle is controlled by the Android OS. Activities are unlike normal classes which are instantiated by the user code and are guaranteed to be available till they are no longer referenced.

Solution 3:

I believe the reason that Activities dont have have getters and setter is related to the lifecycle of an Activity. You really shouldn't guarantee that other Activities are alive since if they are not onScreen the system can clean them up at any give time.

However, to follow your pattern, you extend Application and use getters and setters for that. How to declare global variables in Android?

Solution 4:

Mainly because the whole process of sending an intent is not that simple. An intent can travel through the system, between processes etc... in short the object you created is not the same object that is received at the end (this can be proven if trying to extend an intent class, send it to another activity and try to cast it back to your extended class on the other end, its simply not the same object).

Now i also really hate this, thats why i have created some base classes that help me work with intents (i call them BundleWrappers) which would work something like this:

you create a POJO with getters/setters, you fill that object and use it however you like,

then when the time comes just serialize into a bunle and deserialize it into the same object on the other end.

then you will have the same object with getters and setters in the other activity as well.

The main reason intents suck is that you have to find a way to keep track of all the keys for the extras, and the additional implementation for serializing the bundle.

still even with my method its not easy to use intents but it is the best i have found so far in terms of performance and object organization.

publicabstractclassBundleWrapperimplementsParcelable {

    protectedstaticfinalStringKEY_PARCELABLE="key_parcelable";

    publicstaticfinalStringTAG= BundleWrapper.class.getSimpleName();

    publicBundleWrapper() {
        super();
    }

    abstract Parcelable getParcelable();

    public Bundle toBundle(){
        finalBundlebundle=newBundle();
        Parcelableparcelable= getParcelable();
        if (parcelable != null) {
            bundle.setClassLoader(parcelable.getClass().getClassLoader());
            bundle.putParcelable(KEY_PARCELABLE, parcelable);
        }
        return bundle;
    }

    publicstatic Object fromBundle(final Intent intent) {
        return fromBundle(intent.getExtras());
    }

    publicstatic Object fromBundle(final Bundle bundle) {
        if (bundle != null && bundle.containsKey(KEY_PARCELABLE)) {
            bundle.setClassLoader(BundleWrapper.class.getClassLoader());
            return bundle.getParcelable(KEY_PARCELABLE);
        }
        returnnull;
    }

}

Here is my base class, for using it you simply extend it and implement parcelable(the retarded part of the process :):

publicclassWebViewFragmentBundleextendsBundleWrapperimplementsParcelable {

    publicstatic final StringTAG = WebViewFragmentBundle.class.getSimpleName();

    privateString url;
    publicWebViewFragmentBundle() {
        super();
    }

    publicWebViewFragmentBundle(Parcel source) {
        this.url = source.readString();
    }

    publicStringgetUrl() {
        return url;
    }


    publicvoidsetUrl(String url) {
        this.url = url;
    }

    @OverrideParcelablegetParcelable() {
        returnthis;
    }

    @Overridepublic int describeContents() {
        return0;
    }

    @OverridepublicvoidwriteToParcel(Parcel dest, int flags) {
        dest.writeString(url);
    }

    publicstatic final Parcelable.Creator<WebViewFragmentBundle> CREATOR = newParcelable.Creator<WebViewFragmentBundle>() {
        @OverridepublicWebViewFragmentBundlecreateFromParcel(Parcel source) {
            returnnewWebViewFragmentBundle(source);
        }

        @OverridepublicWebViewFragmentBundle[] newArray(int size) {
            returnnewWebViewFragmentBundle[size];
        }
    };


}

and for a use case:

publicstaticvoidlaunchAugmentedRealityActivityForResult(final Activity context, WebViewFragmentBundle wrapper){
        final Intent intent = newIntent(context, Augmented.class);
        intent.putExtras(wrapper.toBundle());
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        context.startActivityForResult(intent, AUGMENTED_RESULT_CODE);
    }

and cast it on the other end like:

(WebViewFragmentBundle)BundleWrapper.fromBundle(getIntent());

Solution 5:

You are right when it comes to basic Class structure. However if, you consider activity lifecycle and memory management keeping whole activity alive for accessing small amount of data is not logical.

Post a Comment for "Why Aren't Getters Preferred When Accessing Variables Between Activities?"