问题
I want to create some plugin example for android, so I have 3 projects for it:
ExternalLibInterface - contains IExternalLib
, and builds to externallibinterface.jar
file
package com.example.externallibinterface;
public interface IExternalLib {
public String someMethod( String param );
}
ExternalLib - contains externallibinterface.jar
and SomeClass implements IExternalLib
, builds to externallib.apk
package com.example.externallib;
import com.example.externallibinterface.IExternalLib;
public class SomeClass implements IExternalLib {
public String someMethod(String arg0) {
return arg0;
}
}
SomeApp - contains externallibinterface.jar
and class for activity - application where I load external apk and class from it.
import com.example.externallibinterface.IExternalLib;
import dalvik.system.PathClassLoader;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String apkToLoad = null;
String externalPackagePath = "com.example.externallib";
String externalClassPath = "com.example.externallib.SomeClass";
try {
apkToLoad = getPackageManager()
.getApplicationInfo( externalPackagePath, MODE_PRIVATE ).sourceDir;
} catch ( PackageManager.NameNotFoundException e ) {
e.printStackTrace();
}
PathClassLoader pathClassLoader =
new PathClassLoader( apkToLoad,
ClassLoader.getSystemClassLoader() );
try {
Class<?> c = Class.forName( externalClassPath, true, pathClassLoader );
Object someClassInstance = c.newInstance();
//exception ClassCastException here
IExternalLib i = (IExternalLib) someClassInstance;
i.someMethod( "some string" );
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch ( ClassCastException e ) {
e.printStackTrace();
}
}
}
But when I cast Object someClassInstance
to IExternalLib
I get ClassCastException
.
Why? IExternalLib
is defined in 3rd place (in externallibinterface.jar
).
回答1:
It could happen when different class loaders are loading the class. Make sure to build the whole setup at once so that only one class loader is responsible for loading the classes. It happens frequently when you are just re-deploying a particular .war file onto a existing system. Please see this for more insight can't cast to implemented interface
回答2:
Try the following:
Class<? extends IExternalLib> l_clazz; // our expected class
Class<?> clazz = Class.forName("com.example.externallib.SomeClass"); // our unknown class
// check if our unknown class can be cast to our expected class
if ((l_clazz = clazz.asSubclass(IExternalLib.class)) != null) {
IExternalLib i = l_clazz.newInstance();
i.someMethod( "some string" );
}
来源:https://stackoverflow.com/questions/12383376/classcastexception-when-casting-class-forname-object-to-interface-implemented-by