6

I have a app that recieve a dex file from server then save it on sdcard and load it for

doing some functions.I am loading a my app's class from my dex file as following

dex file

public class Main  {


    public void onCreate() 
    {
        System.out.print("------------onCreate------------");
        try {
             final ClassLoader classloader = ClassLoader.getSystemClassLoader();
            final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.myapp.M");
            final Object myInstance  = classToLoad.newInstance();
            final Method doSomething = classToLoad.getMethod("doSomething");
            doSomething.invoke(myInstance);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

app code

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        try {
            final String libPath = Environment.getExternalStorageDirectory() + "/Lib/lib.apk";
            final File tmpDir = getDir("dex", 0);
            final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
            final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("com.example.lib.Main");
            final Object myInstance  = classToLoad.newInstance();
            final Method doSomething = classToLoad.getMethod("onCreate");
            doSomething.invoke(myInstance);
            } catch (Exception e) {
            e.printStackTrace();
        }
    }

M class in my app

public class M {
public void doSomething()
{
    Log.e("doSomething", "--------------------doSomething----");
}
}

but it have me following error.what is wrong in my code

11-19 08:24:12.718: W/System.err(10867): java.lang.ClassNotFoundException: Didn't find class "com.example.myapp2.M" on path: .
11-19 08:24:12.738: W/System.err(10867):    at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:65)
11-19 08:24:12.747: W/System.err(10867):    at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
11-19 08:24:12.758: W/System.err(10867):    at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
11-19 08:24:12.758: W/System.err(10867):    at com.example.lib.Main.onCreate(Main.java:15)
11-19 08:24:12.768: W/System.err(10867):    at java.lang.reflect.Method.invokeNative(Native Method)
11-19 08:24:12.788: W/System.err(10867):    at java.lang.reflect.Method.invoke(Method.java:511)
11-19 08:24:12.788: W/System.err(10867):    at com.example.myapp2.MainActivity.onCreate(MainActivity.java:28)
11-19 08:24:12.798: W/System.err(10867):    at android.app.Activity.performCreate(Activity.java:5104)
11-19 08:24:12.818: W/System.err(10867):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-19 08:24:12.828: W/System.err(10867):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
11-19 08:24:12.828: W/System.err(10867):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
11-19 08:24:12.828: W/System.err(10867):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-19 08:24:12.828: W/System.err(10867):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
11-19 08:24:12.828: W/System.err(10867):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-19 08:24:12.838: W/System.err(10867):    at android.os.Looper.loop(Looper.java:137)
11-19 08:24:12.847: W/System.err(10867):    at android.app.ActivityThread.main(ActivityThread.java:5041)
11-19 08:24:12.847: W/System.err(10867):    at java.lang.reflect.Method.invokeNative(Native Method)
11-19 08:24:12.847: W/System.err(10867):    at java.lang.reflect.Method.invoke(Method.java:511)
11-19 08:24:12.857: W/System.err(10867):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-19 08:24:12.898: W/System.err(10867):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-19 08:24:12.898: W/System.err(10867):    at dalvik.system.NativeStart.main(Native Method)
2
  • 1
    What is ambiguous to you in message ClassNotFoundException: Didn't find class on path . Commented Nov 19, 2013 at 9:46
  • "path".can I access to classes of my app from dex file by classloader.if yes how specify path for accessing? Commented Nov 19, 2013 at 9:49

4 Answers 4

1

See if you're following these steps.

  1. Do you have the library file as an APK or a JAR containing (Classes.dex) file on the SD Card?
  2. Copy the APK file into a temporary folder into your application director /data/data/your.app.name/tmp. This is important as for security reasons Android doesn't let you load something off the SD card.
  3. Use DexClassLoader as described here -> How to load a Java class dynamically on android/dalvik?
  4. Use this classloader instance for loading any dynamic class files.

If you have more than 1 JAR files then merge them into a single DEX file/APK.

To convert your Java JAR file or classes into DEX you need to use the Android SDK's dx.bat. Here's a sample ANT script to do. This can also be done via Command line too with similar arguments.

<exec executable="dx.bat">
    <arg value="--dex" />
    <arg value="--output=${target.directory.fullpath}/${apk.name}" />
    <arg value="--positions=lines" />
    <arg path="${classes.directory.full.path}" />
</exec>
Sign up to request clarification or add additional context in comments.

5 Comments

can i access to my app's classes from my jar file?can you explain how I can do it?
I want from a my jar file's class call a method of my app
Yes your plugged-in JAR (DEX format) files can call the methods of your application without explicitly doing anything as it must act as a Parent Class Loader.
See the constructor for DexClassLoader where you set the parent class loader as one of the input. DexClassLoader. You can get the Parent Class Loader using activity.getClassLoader() method to pass into the DexClassLoader() constructor
i used above code in jar file and i get that error again.what is path in error?
1

I found my answer I need change

final Class<Object> classToLoad = (Class<Object>)classloader.loadClass("com.example.myapp.M");

to

final Class<Object> classToLoad = (Class<Object>)Class.forName("com.example.myapp.M");

in my dex file

3 Comments

its strange ho wthis worked for you.You are not mentioning your .jar file path anywhere...
So if you do this, does it then load all the other classes that com.example.myapp.M needs as well (that aren't already loaded)?
Zohreh did you load class files from the SD card? Or some other External Storage Directory? I'm curious because @Swaroop said you couldn't load them from the SD card.
0

@zohreh Replace the below line

final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());

to

final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, ClassLoader.getSystemClassLoader());

Comments

0

The listed answers didn't work for me. However, getting the ClassLoader via Thread.currentThread().getContextClassLoader() turned out to work:

final Class<Object> classToLoad = (Class<Object>) Class.forName("com.example.myapp.M", true, Thread.currentThread().getContextClassLoader());

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.