无法通过setClassName在Android中使用不同的包启动新的Intent

时间:2012-03-29 10:31:21

标签: android android-intent

我想动态启动一个新的Intent。因此setClassName似乎是最佳选择。

首先,我在Manifest中定义了3个活动

<activity android:name="com.example.pkg2.Act" />
<activity android:name="com.example.pkg1.Act1" />
<activity android:name="com.example.pkg1.Act2" />

来自com.example.pkg2.Act

Intent intent = new Intent();
if(index == 0) intent.setClassName(Act.this, "com.example.pkg1.Act1");
else intent.setClassName(Act.this, "com.example.pkg1.Act2");
startActivity(intent);

并且会得到这个例外:

Unable to find explicit activity class {com.example.pkg2.Act/com.example.pkg1.Act1}; have you declared this activity in your AndroidManifest.xml?

看起来我们只能使用setClassName来动态启动新的Activity,但是在同一个包中。

有什么想法解决这个问题吗?感谢所有帮助。

9 个答案:

答案 0 :(得分:18)

setClassName将包上下文作为第一个参数setClassName(Context packageContext, String className)

Intent intent = new Intent();
if(index == 0) {
  intent.setClassName("com.example.pkg1", "com.example.pkg1.Act1");
} else {
  intent.setClassName("com.example.pkg1", "com.example.pkg1.Act2");
  startActivity(intent);
}

并在

<activity android:name="com.example.pkg2.Act" />
<activity android:name="com.example.pkg1.Act1" />
<activity android:name="com.example.pkg1.Act2" />

或者你试试这个:

if(index == 0) {
  Intent intent = new Intent(Intent.ACTION_MAIN)
    .addCategory(intent.CATEGORY_LAUNCHER)
    .setClassName("com.example.pkg1", "com.example.pkg1.Act1")
    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    .addFlags(Intent.FLAG_FROM_BACKGROUND)
    .setComponent(new ComponentName("com.example.pkg1", "com.example.pkg1.Act1"));
  getApplicationContext().startActivity(intent);
} else {
  Intent intent  = new Intent(Intent.ACTION_MAIN)
    .addCategory(intent.CATEGORY_LAUNCHER)
    .setClassName("com.example.pkg1", "com.example.pkg1.Act2")
    .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    .addFlags(Intent.FLAG_FROM_BACKGROUND)
    .setComponent(new ComponentName("com.example.pkg1", "com.example.pkg1.Act2"));
  getApplicationContext().startActivity(intent);
}

答案 1 :(得分:3)

第一个参数是位于 build.gradle 文件中的 applicationId

第二个参数是包的类的完整路径。 例如: intentObj.setClassName(&#34; applicatioId&#34;,&#34; com.youCompany.yourAppName.YourClassName&#34;)

答案 2 :(得分:0)

按照语法编写setClassName()方法:

 setClassName( pkgName, className ) 

答案 3 :(得分:0)

您可以使用以下方法在包上下文中创建intent:

    Intent intent = new Intent(this, MyActivity.class);
    intent.setAction(Intent.ACTION_VIEW);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

这样就可以保留通用代码。

HTH

答案 4 :(得分:0)

intent.setClassName(packageName,className);

其中
packageName - 实现所需组件的包的名称,即调用者所属的包 className - 类[来自不同包]的完全限定名称

来自com.example.pkg2.Act

intent.setClassName("com.example.pkg2", "com.example.pkg1.Act1");

答案 5 :(得分:0)

使用此代码,你会没事的。

Intent intent = new Intent();
String resourcePackageName = getResources().getResourcePackageName(R.string.some_defined_resource);
intent.setClassName(getApplicationContext().getPackageName(),resourcePackageName + ".SubPackageName[/if any/].ClassName");
startActivity(intent);

答案 6 :(得分:0)

您也可以这种方式启动活动。试试这个

Intent intent = new Intent();
Class<?> activityClass = Class.forName("your.application.package.name." + NameOfClassToOpen); 
intent.setClass(this, activityClass);
  

并且为了使用 setClassName 。你应该提供 packageName ,它的类路径也是

intent.setClassName("your.application.package.name", "your.application.package.name.activityClass");

答案 7 :(得分:0)

最可能的原因是给定的类名不是链接到pkg2的类。这是我用来在AndroidInstumentationTest应用程序中启动意图的代码段。

    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.setClassName("com.xxx.android.app",
            "com.xxx.android.app.MainActivity")
            .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mActivity = instrumentation.startActivitySync(intent);

此代码可以从我的应用模块(具有MainActivity类)运行时很好地运行。如果我尝试在没有链接到MainActivity类的模块中使用它,它将无法正常工作。从我对原始问题陈述的阅读中,似乎用户“ anticafe”说他正在尝试这样做。我的猜测是,内部会调用“ Class.forName(className,classLoader),其中classLoader是给定程序包的ClassLoader。当然,由于该程序包未链接,将失败。

是的,至少在某些情况下,您确实需要添加标记“ FLAG_ACTIVITY_NEW_TASK”,就像其他人建议的那样!

答案 8 :(得分:-1)

intent.setClassName(Act.this, Act1.class);