使用DexClassLoader执行自定义类加载

时间:2013-09-11 03:04:14

标签: android

我希望使用DexClassLoader按照教程http://android-developers.blogspot.pt/2011/07/custom-class-loading-in-dalvik.html

执行自定义类加载

首先,我通过设置android.library=false来使用Ant来构建facebook。

  • APK将生成facebook-release.apk
  • 我在dex2jar内使用classes.dex和反编译器检查facebook-release.apk,对我来说似乎没问题。 enter image description here

然后,我将此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;
    }

通过记录DexClassLoaderdexInternalStoragePath,我已确认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)

我有什么遗漏的吗?

0 个答案:

没有答案