我遇到了一点麻烦。任何帮助都将不胜感激。我有一个应用程序,我想使用DexClassLoader来加载另一个apk文件。
下面是我的代码:
DexClassLoader dLoader = new DexClassLoader("/sdcard/download/test.apk","/sdcard/download",null,ClassLoader.getSystemClassLoader().getParent());
Class calledClass = dLoader.loadClass("com.test.classname");
Intent it=new Intent(this, calledClass);
it.setClassName("com.test", "com.test.classname");
startActivity(it);现在我已经安装了test.apk,所以当我运行上面的代码时,它工作得很好,并启动了应用程序。但是,我希望能够在没有安装test.apk的情况下运行它(因为这会破坏应用程序的全部功能)。所以我卸载了它,当我再次运行我的应用程序时,我得到了这个错误:
android.content.ActivityNotFoundException: Unable to find explicit
activity class {com.test/com.test.classname}; have you declared this
activity in your AndroidManifest.xml.所以我有点迷惑了。此活动在我试图运行的apk的清单中声明。我无法在我的应用程序清单中声明它。有什么想法吗?
谢谢,克雷格
发布于 2010-10-26 16:56:11
尝试使用安卓的PathClassLoader
String packagePath = "com.mypackage";
String classPath = "com.mypackage.ExternalClass";
String apkName = null;
try {
apkName = getPackageManager().getApplicationInfo(packagePath,0).sourceDir;
} catch (PackageManager.NameNotFoundException e) {
// catch this
}
// add path to apk that contains classes you wish to load
String extraApkPath = apkName + ":/path/to/extraLib.apk"
PathClassLoader pathClassLoader = new dalvik.system.PathClassLoader(
apkName,
ClassLoader.getSystemClassLoader());
try {
Class<?> handler = Class.forName(classPath, true, pathClassLoader);
} catch (ClassNotFoundException e) {
// catch this
}发布于 2014-08-17 05:17:26
虽然这个问题很老,但我还是会回答的,因为我有点费力地为你的相同问题找到了一个明确的答案。首先,我想强调的是,您问题中的一个明确要求是从尚未安装在设备上的.apk加载一个类。因此,使用getPackageManager()调用包管理器并为其提供包路径显然会导致NameNotFoundException,因为设备上没有安装包含该包的.apk。
因此,从设备上未安装的 .apk 文件加载类的方法是使用DexClassLoader,如下所示:
1-确保您的SD卡上的某个目录中有.apk文件。我已经在我的SD卡的下载文件夹中找到了Offloadme.apk。
2-在您的AndroidManifest.xml中添加读取权限,以允许您的应用程序从清单中读取。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>3-使用以下定义来定义.apk的路径、apk内的类名以及要调用的类中的方法名:
final String apkFile =Environment.getExternalStorageDirectory().getAbsolutePath()+"/Download/Offloadme.apk";
String className = "com.khaledalanezi.offloadme.SimpleCalculator";
String methodToInvoke = "add"; 4-使用DexClassLoader加载.apk,并使用反射调用SimpleCalculator类中的add方法,如下所示:
final File optimizedDexOutputPath = getDir("outdex", 0);
DexClassLoader dLoader = new DexClassLoader(apkFile,optimizedDexOutputPath.getAbsolutePath(),
null,ClassLoader.getSystemClassLoader().getParent());
try {
Class<?> loadedClass = dLoader.loadClass(className);
Object obj = (Object)loadedClass.newInstance();
int x =5;
int y=6;
Method m = loadedClass.getMethod(methodToInvoke, int.class, int.class);
int z = (Integer) m.invoke(obj, y, x);
System.out.println("The sum of "+x+" and "+"y="+z);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}请注意,在我的简单示例中,我使用从我的SD卡上存储的Offloadme.apk文件加载的SimpleCalculator类中可用的add方法将两个数字相加,并且我能够打印正确的答案11。
发布于 2010-09-16 07:31:35
你不能这么做。即使你能够从外部文件访问类,Android仍然不知道它们。而且你不是直接运行活动,而是通过请求Android来运行它们,所以它们必须注册/安装到系统中。
https://stackoverflow.com/questions/2903260
复制相似问题