3

I want to have an activity class, e.g. ActivityLegacy, for API levels older than level x and an activity class, e.g. ActivityNew for newer devices.

Is it possible that I choose the proper implementation at runtime and load it? I don't want to start a new intent.

Petrakeas
  • 1,521
  • 15
  • 28
  • I don't think that this is possible. Either you handle it in one activity or use different activities and therefore intents. – Thomas R. Sep 28 '15 at 12:15

3 Answers3

6

I don't want to start a new intent.

Um, well, the only way to get an activity to appear on the screen is via an Intent. Somebody is calling startActivity() or kin. Whether that is your code or third-party code would depend on circumstance.

Is it possible that I choose the proper implementation at runtime and load it?

If you are the one calling startActivity(), craft the Intent for your desired class.

If you are not the one calling startActivity(), I would recommend that you have just one activity, then use fragments (or something similar) for the activity contents, so that you can cleanly load in the right fragment based on API level. Otherwise, you have two main options that I can think of.

If the outside party is using an implicit Intent (e.g., action string) to start up your activity, you could have two <activity> elements for the same <action> in the manifest, one for each of your two implementations. However, they would each have android:enabled pointing to boolean resources, where those resources would vary by API level. Suppose you want a different activity on Android 6.0 than on older versions. res/values/bools.xml would define is23 to be false and isPre23 to be true. res/values-v23/bools.xml would define is23 to be true and isPre23 to be false. Your pre-23 activity would have android:enabled="@bool/isPre23"; your 23-and-above activity would have android:enabled="@bool/is23". This way, only one activity will be enabled for that action string, based on API level.

If you are in some screwball scenario where an explicit Intent that you do not control is the one that is being used to start the activity, you would need a total of three activities:

  1. The pre-23 one.

  2. The 23-and-over one.

  3. The one identified by that explicit Intent, which would use Theme.NoDisplay (so it has no UI). In onCreate(), you would call startActivity() for the right activity based on API level, then call finish(), to pass control to the desired activity.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • What I mean by saying that I don't want to start a new Intent is that I wanted to avoid the "transparent" activity paradigm which you describe in the end. Also, the activity called would be selected by 3rd party code (by the launcher or an intent from another app) according to my manifest. The solution with the `android:enabled` and the different resources per API level is great. It requires double definitions for the entry activities in the manifet but I find it more clean that the transparent activity method. – Petrakeas Sep 28 '15 at 16:25
0

You can only choose the next activity programmatically. If you want to choose the first activity in your app, I recommend to start a transparent activity on app launch and then start an different activity. Read this to create a transparent activity. Also in the code do this.

Community
  • 1
  • 1
DaviF
  • 369
  • 3
  • 11
0

Say you start activities with something like:

Intent i = new Intent(getActivity(), ActivityToStart.class);
startActivity(i);

now you realize you need to do something different for API 15 and below so you can add a static method to the original activity to give you the alternative Class:

public static Class correctClass(){
    if (android.os.Build.VERSION.SDK_INT > Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1){
        return ActivityToStart.class;
    else {
        return ActivityToStartLegacy.class;
    }
}

Now replace .class with .correctClass() where necessary.

Intent i = new Intent(getActivity(), ActivityToStart.correctClass());
startActivity(i);

Add as many alternate classes as you need but always call the one static method in the original activity.

dabombace
  • 21
  • 1