Note that there are some explanatory texts on larger screens.

plurals
  1. POHow can I load a class from a jar file packaged in my .apk file?
    primarykey
    data
    text
    <p>I am trying to load a plugin implementation of an interface from a jar file which is in the /assets directory of my .apk file. The only way I've been able to get this to work is by extracting the jar file to private external storage and then passing that file to the DexClassLoader. </p> <p>That works, but why should the jar have to exist in two places (the .apk and private external storage)? The DexClassLoader has to have a file path as its argument. </p> <p>Is there a way to give it a direct path to the file that is in the /assets folder so that I don't have to use up external storage for an extra copy of what's already present?</p> <p>Here are the relevant code snippets:</p> <pre><code>// somewhere in my main Activity ... final File aExtractedDexFile = new File(getDir("dex", Context.MODE_PRIVATE), LIBRARY_DEX_JAR); extractDexTo(aExtractedDexFile); loadLibraryProvider(aExtractedDexFile); </code></pre> <p>and</p> <pre><code>/** Extract the jar file that contains the implementation class.dex and place in private storage */ private void extractDexTo(File tJarInternalStoragePath) { BufferedInputStream aJarInputStream = null; OutputStream aDexOutputStream = null; try { aJarInputStream = new BufferedInputStream(getAssets().open(LIBRARY_DEX_JAR)); aJarOutputStream = new BufferedOutputStream(new FileOutputStream(tJarInternalStoragePath)); byte[] buf = new byte[BUF_SIZE]; int len; while ((len = aJarInputStream.read(buf, 0, BUF_SIZE)) &gt; 0) { aJarOutputStream.write(buf, 0, len); } aJarOutputStream.close(); aJarInputStream.close(); } catch (IOException e) { if (aDexOutputStream != null) { try { aJarOutputStream.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } if (aJarInputStream != null) { try { aJarInputStream.close(); } catch (IOException ioe) { ioe.printStackTrace(); } } } } </code></pre> <p>and</p> <pre><code>/** Use DexClassLoader to load the classes from LibraryProvider */ private void loadLibraryProvider(File tFile) { // Internal storage where the DexClassLoader writes the optimized dex file to. final File aOptimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE); // Initialize the class loader with the secondary dex file. DexClassLoader cl = new DexClassLoader(tFile.getAbsolutePath(), aOptimizedDexOutputPath.getAbsolutePath(), null, getClassLoader()); Class&lt;?&gt; aLibProviderClazz = null; try { // Load the library class from the class loader. aLibProviderClazz = cl.loadClass(LIBRARY_PROVIDER_CLASS); sLibraryProvider = (LibraryInterface) aLibProviderClazz.newInstance(); } catch (Exception exception) { // Handle exception gracefully here. exception.printStackTrace(); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload