Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to keep a jar file external but still use its classes in my Android project?

I need to have a jar file located in a main/assets directory within an Android project. It is important the jar file is located there.

With my main Android project is there a way to reference this jar file in my code and to use its classes?

To be clear I don't want to add the jar to the main project once compiled.

EDIT: I have tried the link below and it seems to load the Class file I've stated. But I'm strugging how to define constructor arguments for the dynamically loaded Class.

android-custom-class-loading-sample

EDIT2

Nearly there. I've confirmed the class is loaded from my classes.jar. I'm stuck instantiating it though.

On the licenseValidatorClazz.getConstructor line I get the error below. I'm guessing I'm missing something from my Interface file?

java.lang.NoSuchMethodException: [interface com.google.android.vending.licensing.Policy, interface com.google.android.vending.licensing.DeviceLimiter, interface com.google.android.vending.licensing.LicenseCheckerCallback, int, class java.lang.String, class java.lang.String]

    public Class licenseValidatorClazz = null;
    public LicenseValidator validator;

    ...

    // Initialize the class loader with the secondary dex file.
    DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
    optimizedDexOutputPath.getAbsolutePath(),
    null,
    mContext.getClassLoader());

        try {
            // Load the library class from the class loader.
            licenseValidatorClazz = cl.loadClass("com.google.android.vending.licensing.LicenseValidator");

            validator = (LicenseValidator) licenseValidatorClazz.getConstructor(Policy.class,DeviceLimiter.class,LicenseCheckerCallback.class,int.class,String.class,String.class).newInstance(ddd, new NullDeviceLimiter(),
                    callback, generateNonce(), mPackageName, mVersionCode);

        } catch (Exception exception) {
            // Handle exception gracefully here.
            exception.printStackTrace();
        }

I have an Interface which contains the functions to pass to the loaded class.

public interface LicenseValidator
{
    public LicenseCheckerCallback getCallback();
    public int getNonce();
    public String getPackageName();
    public void verify(PublicKey publicKey, int responseCode, String signedData, String signature);
    public void handleResponse(int response, ResponseData rawData);
    public void handleApplicationError(int code);
    public void handleInvalidResponse();
}
like image 261
zeroprobe Avatar asked Oct 21 '14 13:10

zeroprobe


2 Answers

TO use an external jar to be associated with your application and use it during runtime, it needs to be in dalvik format since normal jars cannot work under dalvikVM.

  1. Convert your files using the dx tool
  2. using aapt cmd , add those classes.dex to your jar file.
  3. Now this jar which contains files in dalvik format can be loaded into our project.

Here is a post which explains the procedure to accomplish it.

like image 168
vembutech Avatar answered Sep 20 '22 21:09

vembutech


There are steps to accomplish this.

  1. You have to make a copy of your JAR file into the private internal storage of your aplication.

    1. Using the dx tool inside the android folder, you have to generate a classes.dex file associated with the JAR file. The dx tool will be at the location /android-sdks/build-tools/19.0.1 (this file is needed by the Dalvik VM, simply jar can not be read by the dalvik VM))

    2. Using the aapt tool command which is also inside the same location, you have to add the classes.dex to the JAR file.

This JAR file could be loaded dynamically using DexClassLoader.

If you are making a JAR from any one your own library, you have to do this steps (1-4) every time when there is a change in your library source code. So you can automate this steps by creating a shell script(in Mac/Linux/Ubuntu) or batch scripts(in Windows). You can refere this link to understand how to write shell scripts.

Note : One situation for implementing this method is, when it is impossible to add the JAR files directly to the build path of core project and need to be loaded dynamically at run time. In normal cases the JAR files could be added to the build path.

please check this link for the detailed code and implementation.

How to load a jar file at runtime

Android: How to dynamically load classes from a JAR file?

Hope this helps!!

like image 43
Blackhat002 Avatar answered Sep 22 '22 21:09

Blackhat002