如何将 cordova 插件动态加载到 android 应用程序中
How to load cordova plugin dynamically into android app
我使用以下代码将我的 class 动态加载到 android 应用程序。 (注:加载成功)
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String fileInput = file.getAbsolutePath() + "/file.jar";
File optimizedDexOutputPath = activity.getDir("dex", Context.MODE_PRIVATE);
String fileOutput = optimizedDexOutputPath.getAbsolutePath();
DexClassLoader classLoader = new DexClassLoader(fileInput, fileOutput, null, getClass().getClassLoader());
try {
Class<?> helloClass = classLoader.loadClass("HelloClass");
Toast.makeText(activity, "Loaded success: " + helloClass.toString(), Toast.LENGTH_SHORT).show();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
我有以下 cordova config.xml:
<feature name="HelloClass">
<param name="android-package" value="HelloClass" />
</feature>
当我从 javascript 调用执行方法时,出现以下错误。
05-12 18:06:19.180: W/System.err(17862): java.lang.ClassNotFoundException: HelloClass
05-12 18:06:19.180: W/System.err(17862): 引起: java.lang.NoClassDefFoundError: HelloClass
05-12 18:06:19.180: W/System.err(17862): ... 13 更多
05-12 18:06:19.190: W/System.err(17862): 原因: java.lang.ClassNotFoundException: 在路径上找不到 class "HelloClass": /data/app/sandbox.apk
我想知道这里出了什么问题。非常感谢任何帮助。
我假设您想将外部 class 从 cordova 插件动态加载到 android 应用程序中。
从上面提到的情况来看,您使用 DexClassLoader 加载 class 的方法似乎没问题。但是,要使 class 在您从 javascript 调用它时可用,您需要在调用 cordova execute 方法后立即加载 class。
您可以修改现有的codovaPluginManager.java如下:
private CordovaPlugin instantiatePlugin(String className) {
CordovaPlugin ret = null;
try {
Class<?> c = null;
if ("HelloClass".equals(className)) {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String fileInput = file.getAbsolutePath();
File optimizedDexOutputPath = this.ctx.getActivity().getDir("dex", Context.MODE_PRIVATE);
String fileOutput = optimizedDexOutputPath.getAbsolutePath();
DexClassLoader classLoader = new DexClassLoader(fileInput, fileOutput, null, getClass().getClassLoader());
try {
c = classLoader.loadClass(className);
ret = (CordovaPlugin) c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
else {
if ((className != null) && !("".equals(className))) {
c = Class.forName(className);
}
if (c != null & CordovaPlugin.class.isAssignableFrom(c)) {
ret = (CordovaPlugin) c.newInstance();
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error adding plugin " + className + ".");
}
return ret;
}
现在,您应该可以毫无问题地从 .js 执行 HelloClass 中的方法。
我使用以下代码将我的 class 动态加载到 android 应用程序。 (注:加载成功)
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String fileInput = file.getAbsolutePath() + "/file.jar";
File optimizedDexOutputPath = activity.getDir("dex", Context.MODE_PRIVATE);
String fileOutput = optimizedDexOutputPath.getAbsolutePath();
DexClassLoader classLoader = new DexClassLoader(fileInput, fileOutput, null, getClass().getClassLoader());
try {
Class<?> helloClass = classLoader.loadClass("HelloClass");
Toast.makeText(activity, "Loaded success: " + helloClass.toString(), Toast.LENGTH_SHORT).show();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
我有以下 cordova config.xml:
<feature name="HelloClass">
<param name="android-package" value="HelloClass" />
</feature>
当我从 javascript 调用执行方法时,出现以下错误。
05-12 18:06:19.180: W/System.err(17862): java.lang.ClassNotFoundException: HelloClass 05-12 18:06:19.180: W/System.err(17862): 引起: java.lang.NoClassDefFoundError: HelloClass 05-12 18:06:19.180: W/System.err(17862): ... 13 更多 05-12 18:06:19.190: W/System.err(17862): 原因: java.lang.ClassNotFoundException: 在路径上找不到 class "HelloClass": /data/app/sandbox.apk
我想知道这里出了什么问题。非常感谢任何帮助。
我假设您想将外部 class 从 cordova 插件动态加载到 android 应用程序中。
从上面提到的情况来看,您使用 DexClassLoader 加载 class 的方法似乎没问题。但是,要使 class 在您从 javascript 调用它时可用,您需要在调用 cordova execute 方法后立即加载 class。
您可以修改现有的codovaPluginManager.java如下:
private CordovaPlugin instantiatePlugin(String className) {
CordovaPlugin ret = null;
try {
Class<?> c = null;
if ("HelloClass".equals(className)) {
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
String fileInput = file.getAbsolutePath();
File optimizedDexOutputPath = this.ctx.getActivity().getDir("dex", Context.MODE_PRIVATE);
String fileOutput = optimizedDexOutputPath.getAbsolutePath();
DexClassLoader classLoader = new DexClassLoader(fileInput, fileOutput, null, getClass().getClassLoader());
try {
c = classLoader.loadClass(className);
ret = (CordovaPlugin) c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
else {
if ((className != null) && !("".equals(className))) {
c = Class.forName(className);
}
if (c != null & CordovaPlugin.class.isAssignableFrom(c)) {
ret = (CordovaPlugin) c.newInstance();
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("Error adding plugin " + className + ".");
}
return ret;
}
现在,您应该可以毫无问题地从 .js 执行 HelloClass 中的方法。