简体   繁体   English

来自jar文件的android加载类

[英]android load class from jar file

I have written a Java Classloader to load classes from a .jar file. 我编写了一个Java类加载器来从.jar文件加载类。

However when I load a Class I get a ClassNotFoundException . 但是,当我加载一个类时,我得到一个ClassNotFoundException The .jar file is located in folder assets. .jar文件位于文件夹资产中。 Before the operation I copied the .jar file in another directory. 在操作之前,我将.jar文件复制到另一个目录中。

Why does it happen and how can I load class from jar file? 为什么会发生这种情况?如何从jar文件中加载类?

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.main);
    try {
        final File dexInternalStoragePath = new File(getDir("lib", Context.MODE_PRIVATE), SECONDARY_DEX_NAME);
        (new PrepareDexTask()).execute(dexInternalStoragePath);
        if (dexInternalStoragePath.exists()) {
            final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);

            DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
                    optimizedDexOutputPath.getAbsolutePath(), null, getClassLoader());
            try {
                JarFile jarFile = new JarFile(dexInternalStoragePath.getAbsolutePath());
                Enumeration<?> e = jarFile.entries();

                URL[] urls = { new URL("jar:file:" + dexInternalStoragePath.getAbsolutePath() + "!/") };
                URLClassLoader cl1 = URLClassLoader.newInstance(urls);

                while (e.hasMoreElements()) {
                    JarEntry je = (JarEntry) e.nextElement();
                    if (je.isDirectory() || !je.getName().endsWith(".class")) {
                        continue;
                    }
                    String className = je.getName().substring(0, je.getName().length() - 6);
                    className = className.replace('/', '.');
                    if (className.equals("com.common.lvl.LibraryProvider")) {
                        LibraryInterface lib = (LibraryInterface) Class.forName(className, true,  cl1).newInstance();
                        //Class<?> libProviderClazz = cl1.loadClass(className);
                        //LibraryInterface lib = (LibraryInterface) libProviderClazz.newInstance();
                        lib.CheckLVL(this, "hello");
                    }
                }

                // Class<?> libProviderClazz =
                // cl.loadClass("com.common.lvl.LibraryProvider");
                // LibraryInterface lib = (LibraryInterface)
                // libProviderClazz.newInstance();
                // lib.CheckLVL(this, "hello");
            } catch (Exception ex) {
                Logger.Instance().WriteLine(this, ex.getMessage());
            }
        }
    } catch (Exception ex) {

    }
}

private boolean prepareDex(File dexInternalStoragePath) {
    BufferedInputStream bis = null;
    OutputStream dexWriter = null;

    try {
        bis = new BufferedInputStream(getAssets().open(SECONDARY_DEX_NAME));
        dexWriter = new BufferedOutputStream(new FileOutputStream(dexInternalStoragePath));
        byte[] buf = new byte[BUF_SIZE];
        int len;
        while ((len = bis.read(buf, 0, BUF_SIZE)) > 0) {
            dexWriter.write(buf, 0, len);
        }
        dexWriter.close();
        bis.close();
        return true;
    } catch (IOException e) {
        if (dexWriter != null) {
            try {
                dexWriter.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException ioe) {
                ioe.printStackTrace();
            }
        }
        return false;
    }
}

private class PrepareDexTask extends AsyncTask<File, Void, Boolean> {

    @Override
    protected void onCancelled() {
        super.onCancelled();
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
    }

    @Override
    protected Boolean doInBackground(File... dexInternalStoragePaths) {
        prepareDex(dexInternalStoragePaths[0]);
        return null;
    }
}

Add your jar file, like below 添加你的jar文件,如下所示

go to -> project properties in eclipse -> java build path -> Libraries -> Add External Jar , And browse and locate you jar file. 转到 - > eclipse中的项目属性 - > java build path - > Libraries - > Add External Jar ,并浏览并找到你的jar文件。

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM