47

I'm having a problem with an android application that I'm working on.

My application has several sections and the next screen that loads is based on a string. So, screen 1 of section 1 would be, S1S1.

My question is, how can I start an activity based on a string. I have S1S1 saved in a string, let us call it next activity. Rather than having to type S1S1.class, I need it to come from the string. I've tried everything I can think of and google hasn't helped much.

Some things I've tried are

Intent myIntent = new Intent(nextactivity);
Intent myIntent = new Intent(v.getContext(), getClass().getName().valueOf(nextactivity));
Intent myIntent = new Intent(v.getContext(), Class.forName(nextactivity));

and tried running with

startActivityForResult(myIntent, 0); 

but nothing seems to work. Any ideas?

nima moradi
  • 2,300
  • 21
  • 34
fahadayaz
  • 563
  • 1
  • 4
  • 8

4 Answers4

96

Here is a code by which you can start activity using the name of the activity

String activityToStart = "com.example.MainActivity";
try {
    Class<?> c = Class.forName(activityToStart);
    Intent intent = new Intent(this, c);
    startActivity(intent);
} catch (ClassNotFoundException ignored) {
}

EDIT

Here class name will be full name of the class with the package name. For example if your package name will be x.y.z and if you have Activity name called A then the full name (activityToStart) of the Activity A will be x.y.z.A.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
Dharmendra
  • 33,296
  • 22
  • 86
  • 129
  • I replaced StringClassname with "End", an activity I know exists.. but all i get is a ClassNotFoundException and a java.lang.NullPointerException i replaced mail.this with v.getContext() and I also tried "End.class" but that didn't do anything either. – fahadayaz Apr 22 '11 at 12:12
  • I did try, but since I'm new here and don't have a 15 reputation, it looks like I can't vote yet.. – fahadayaz Apr 22 '11 at 12:52
  • I got error like this: The method setClass(Context, Class>) in the type Intent is not applicable for the arguments (CallAudioManager, Class), I can't understand why. – Corey Jul 04 '17 at 06:48
  • @Dharmendra using com.example.MainActivity to open activity, is it a overhead or computationally is it same as giving the class name as MainActivity.java ? Can u explain what exactly happens inside Class.forName – jayant singh Sep 15 '19 at 17:48
40

An even better way (and one that is used in the system to launch Browser.apk along with other apps that aren't bundled with AOSP):

Intent intent = new Intent();
intent.setClassName("com.android.browser","com.android.BrowserActivity");

context.startActivity(intent);

Alternatively, if you want to check that you can start the Activity from the command line, you can do something like this from your shell:

adb shell
am start com.android.browser/.BrowserActivity
Ehtesh Choudhury
  • 7,452
  • 5
  • 42
  • 48
  • 1
    What happens if the Activity isn't found? An example for when this can happen is with flavored gradle builds that don't include certain classes. – Jon Willis Nov 13 '14 at 18:07
  • 8
    This is the best answer. You can also do this: `intent.setClassName(context, context.getPackageName() + ".MyActivity");` – Richard Jun 04 '15 at 18:52
  • 1
    @JonWillis An `ActivityNotFoundException` will be thrown. The example from @Richard can be simplified even further - there is no need to prepend the package name: `intent.setClassName(context, ".MyActivity");` – friederbluemle Sep 14 '17 at 11:48
-1

I am not aware of solution but i have an alternative.. the way similar to div hide and show in web pages.

if your s1s1 is to loaded low content have them in a linearlayout and keep their visibility gone on loading form s1. when you click on s1 to reach s1s1 hide s1 and set the params of visibility to "visible".

By doing this you can avoid creating a separate activity and this way is also easy to navigate back.

Jana
  • 2,890
  • 5
  • 35
  • 45
-3

Use Enums!

public enum SectionActivity {

  S1S1(MyS1Activity.class),
  S1S2(S2Activity.class);

  private Class<? extends Activity> activityClass;

  private SectionActivity(Class<? extends Activity> clazz) {

   this.activityClass = clazz;
  }

  public Class<? extends Activity> getActivity {
     return activityClass;
  }    
}

Then somewhere in your code:

SectionActivity act = SectionActivity.valueOf(string);
Intent intent = new Intent(this, act.getActivity());
startActivity(intent);
Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
  • This solution worked for me too, but since the other was less code and more direct, it's likely to work faster. This will also have it's uses though.. thanks! – fahadayaz Apr 22 '11 at 12:37
  • I would disagree with you. The other solution uses reflection and also works in try block. It is a question of measure, of course, but I at least I'm not sure whose solution is faster. Also, enum is a final class and it's members are static final, so android will optimize it well. – Vladimir Ivanov Apr 22 '11 at 12:57
  • Interesting! Is there a tool that will let me measure the performance using the different methods? I did get both working so I may as well see which is the more optimised. – fahadayaz Apr 22 '11 at 13:07
  • See this question http://stackoverflow.com/questions/302026/measuring-java-execution-time-memory-usage-and-cpu-load-for-a-code-segment – Vladimir Ivanov Apr 22 '11 at 13:11
  • Thanks! I'll let you know how I get on :) – fahadayaz Apr 22 '11 at 13:35