I want to start a new Intent dynamically. Therefore setClassName
seems the best choice.
First, I define 3 activity in Manifest
intent.setClassName(packageName, className);
where
packageName - The name of the package implementing the desired component, i.e. the package where the caller belongs to.
className - fully qualified name of the class [from different package]
Calling from com.example.pkg2.Act
:
intent.setClassName("com.example.pkg2", "com.example.pkg1.Act1");
The most likely cause of the problem is that the given class name is not a class linked into pkg2. Here's snippet of code that I was using to start an intent in an AndroidInstumentationTest app.
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);
This code works perfectly fine running it from my app module which has the MainActivity class in it. It does not work if I try to use it in a module that doesn't have MainActivity class linked to it. From my read of the original problem statement, that seem likely what user "anticafe" says he was trying to do. My guess is that internally there is a call to "Class.forName(className, classLoader) where classLoader is the ClassLoader for the given package. And of course that'll fail since that package is not linked in.
And yes, you do need to add the flag "FLAG_ACTIVITY_NEW_TASK", as others have suggested, at least for the situations where you do have the class linked in!
You can also launch Activities in this manner. Try this
Intent intent = new Intent();
Class<?> activityClass = Class.forName("your.application.package.name." + NameOfClassToOpen);
intent.setClass(this, activityClass);
And in order to use setClassName. You should supply it with packageName and its class path too like
intent.setClassName("your.application.package.name", "your.application.package.name.activityClass");