如何使用字符串中的类名启动新的 android 活动?

Posted

技术标签:

【中文标题】如何使用字符串中的类名启动新的 android 活动?【英文标题】:How can I start a new android activity using class name in a string? 【发布时间】:2011-08-10 22:09:28 【问题描述】:

我正在使用的 android 应用程序有问题。

我的应用程序有几个部分,加载的下一个屏幕基于一个字符串。因此,第 1 部分的屏幕 1 将是 S1S1。

我的问题是,如何根据字符串启动活动。我将 S1S1 保存在一个字符串中,让我们将其称为下一个活动。我不需要输入 S1S1.class,而是需要它来自字符串。我已经尝试了所有我能想到的方法,但谷歌并没有多大帮助。

我尝试过的一些事情是

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

并尝试运行

startActivityForResult(myIntent, 0); 

但似乎没有任何效果。有什么想法吗?

【问题讨论】:

【参考方案1】:

这是一个代码,您可以通过该代码使用活动的名称来启动活动

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

编辑

这里的类名将是类的全名和包名。 例如,如果您的包名称为x.y.z,并且如果您的活动名称为A,则活动的全名A 将为x.y.z.A

【讨论】:

我用“End”替换了 StringClassname,我知道存在一个活动。但我得到的只是 ClassNotFoundException 和 java.lang.NullPointerException 我用 v.getContext() 替换了 mail.this,我也尝试了“End.class”,但也没有做任何事情。 查看编辑后的答案 EDIT @fahadayaz 我试过了,但由于我是新来的,没有 15 的声望,看来我还不能投票.. 我收到这样的错误: Intent 类型中的方法 setClass(Context, Class>) 不适用于参数(CallAudioManager, Class),我不明白为什么。 @Dharmendra 使用 com.example.MainActivity 打开活动,这是开销还是在计算上与将类名指定为 MainActivity.java 相同?你能解释一下 Class.forName 中到底发生了什么【参考方案2】:

一种更好的方式(在系统中用于启动 Browser.apk 以及其他未与 AOSP 捆绑的应用程序):

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

context.startActivity(intent);

或者,如果您想检查是否可以从命令行启动 Activity,您可以在 shell 中执行以下操作:

adb shell
am start com.android.browser/.BrowserActivity

【讨论】:

如果找不到 Activity 会怎样?可能发生这种情况的一个示例是使用不包含某些类的风味 gradle 构建。 这是最好的答案。你也可以这样做:intent.setClassName(context, context.getPackageName() + ".MyActivity"); @JonWillis ActivityNotFoundException 将被抛出。 @Richard 的示例可以进一步简化 - 无需在包名前面添加:intent.setClassName(context, ".MyActivity");【参考方案3】:

我不知道解决方案,但我有一个替代方案.. 类似于 div 在网页中隐藏和显示的方式。

如果您的 s1s1 要加载低内容,请将它们置于线性布局中,并在加载表单 s1 时保持其可见性。当您点击 s1 到达 s1s1 时隐藏 s1 并将可见性参数设置为“可见”。

通过这样做,您可以避免创建单独的活动,并且这种方式也很容易导航回来。

【讨论】:

【参考方案4】:

使用枚举!

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;
      

然后在你的代码中的某个地方:

SectionActivity act = SectionActivity.valueOf(string);
Intent intent = new Intent(this, act.getActivity());
startActivity(intent);

【讨论】:

这个解决方案也适用于我,但由于另一个解决方案的代码更少且更直接,它可能会运行得更快。不过,这也将有它的用途.. 谢谢! 我不同意你的观点。另一种解决方案使用反射,也适用于 try 块。当然,这是一个衡量的问题,但我至少不确定谁的解决方案更快。另外,枚举是一个final类,它的成员是静态final的,所以android会很好地优化它。 有趣!有没有一种工具可以让我使用不同的方法来衡量性能?我确实让两者都工作了,所以我不妨看看哪个更优化。 看到这个问题***.com/questions/302026/… 谢谢!我会让你知道我是怎么过的:)

以上是关于如何使用字符串中的类名启动新的 android 活动?的主要内容,如果未能解决你的问题,请参考以下文章

新 Android在一个APP中通过包名或类名启动另一个APP

Android -- 保活方案

使用类名启动 Activity Android

Android-----Intent中通过startActivity(Intent intent )显式启动新的Activity

如何在不发送 savedInstanceState 的情况下启动新的 Android 活动?

Android开发- Intent和Broadcast Receiver