我希望使用DexClassLoader
按照教程http://android-developers.blogspot.pt/2011/07/custom-class-loading-in-dalvik.html
首先,我通过设置android.library=false
来使用Ant来构建facebook。
dex2jar
内使用classes.dex
和反编译器检查facebook-release.apk
,对我来说似乎没问题。
然后,我将此apk文件包含在我的项目assets
文件夹中。我希望在运行时使用它的类,这就是我所做的。
@Override
protected Boolean doInBackground(File... dexInternalStoragePaths) {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return null;
}
final File dexInternalStoragePath = dexInternalStoragePaths[0];
if (false == dexInternalStoragePath.exists()) {
prepareDex(dexInternalStoragePath);
}
// Internal storage where the DexClassLoader writes the optimized dex file to.
final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
// /data/data/org.yccheok.jstock.gui/app_dex/facebook-release.apk exists : true
Log.i("CHEOK", dexInternalStoragePath.getAbsolutePath() + " exists : " + dexInternalStoragePath.exists());
// /data/data/org.yccheok.jstock.gui/app_outdex exists : true
Log.i("CHEOK", optimizedDexOutputPath.getAbsolutePath() + " exists : " + optimizedDexOutputPath.exists());
// Initialize the class loader with the secondary dex file.
DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
optimizedDexOutputPath.getAbsolutePath(),
null,
getClassLoader());
Class libProviderClazz = null;
try {
// Load the library class from the class loader.
libProviderClazz = cl.loadClass("com.facebook.LibraryProvider");
// Cast the return object to the library interface so that the
// caller can directly invoke methods in the interface.
// Alternatively, the caller can invoke methods through reflection,
// which is more verbose and slow.
LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
// Display the toast!
lib.activateApp(JStockFragmentActivity.this, "470806879684614");
} catch (Exception exception) {
// Handle exception gracefully here.
exception.printStackTrace();
Log.i("CHEOK", exception.toString());
}
return null;
}
通过记录DexClassLoader
和dexInternalStoragePath
,我已确认optimizedDexOutputPath
的所有传入参数都是正确的。
但是,在DexClassLoader.loadClass
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by: java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation
at dalvik.system.DexFile.defineClass(Native Method)
at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:211)
at dalvik.system.DexPathList.findClass(DexPathList.java:315)
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:58)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at org.yccheok.jstock.gui.JStockFragmentActivity$PrepareDexTask.doInBackground(JStockFragmentActivity.java:120)
我有什么遗漏的吗?