0

I have created an app which uses a lot of ad networks sdk.

Because of the big number of libraries used in the project (Ad network SDKs) I had the following problem in GingerBread devices:

E/dalvikvm( 7815): LinearAlloc exceeded capacity (5242880), last=5905

I solved it by creating multiple dex files like explained at http://android-developers.blogspot.fr/2011/07/custom-class-loading-in-dalvik.html

For my specific needs, I created one dex per Ad Network (Library + associated files) and the main part of the project is in the main dex.

To be simple, I put the admob jar in a secondary dex and I am able to displays Admob banners but I can't display Interstitials because they use an activity to display it (com.google.ads.AdActivity). I can't figure how to reference it correctly.

I put in my manifest

        <activity
        android:name="com.google.ads.AdActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />

But I have the following error when I try to display the interstitial.

03-28 12:10:57.741: E/AndroidRuntime(32554): FATAL EXCEPTION: main 03-28 12:10:57.741: E/AndroidRuntime(32554): Process: my.package, PID: 32554 03-28 12:10:57.741: E/AndroidRuntime(32554): java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{my.package/com.google.ads.AdActivity}: java.lang.ClassNotFoundException: Didn't find class "com.google.ads.AdActivity" on path: DexPathList[[zip file "/system/framework/com.google.android.maps.jar", zip file "/data/app/my.package-2.apk"],nativeLibraryDirectories=[/data/app-lib/my.package-2, /vendor/lib, /system/lib]] 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2121) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread.access$800(ActivityThread.java:135) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1196) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.os.Handler.dispatchMessage(Handler.java:102) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.os.Looper.loop(Looper.java:136) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread.main(ActivityThread.java:5017) 03-28 12:10:57.741: E/AndroidRuntime(32554): at java.lang.reflect.Method.invokeNative(Native Method) 03-28 12:10:57.741: E/AndroidRuntime(32554): at java.lang.reflect.Method.invoke(Method.java:515) 03-28 12:10:57.741: E/AndroidRuntime(32554): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 03-28 12:10:57.741: E/AndroidRuntime(32554): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 03-28 12:10:57.741: E/AndroidRuntime(32554): at dalvik.system.NativeStart.main(Native Method) 03-28 12:10:57.741: E/AndroidRuntime(32554): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.ads.AdActivity" on path: DexPathList[[zip file "/system/framework/com.google.android.maps.jar", zip file "/data/app/my.package-2.apk"],nativeLibraryDirectories=[/data/app-lib/my.package-2, /vendor/lib, /system/lib]] 03-28 12:10:57.741: E/AndroidRuntime(32554): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 03-28 12:10:57.741: E/AndroidRuntime(32554): at java.lang.ClassLoader.loadClass(ClassLoader.java:497) 03-28 12:10:57.741: E/AndroidRuntime(32554): at java.lang.ClassLoader.loadClass(ClassLoader.java:457) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.Instrumentation.newActivity(Instrumentation.java:1061) 03-28 12:10:57.741: E/AndroidRuntime(32554): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2112) 03-28 12:10:57.741: E/AndroidRuntime(32554): ... 11 more

Could someone help me with this?

Thanks for your time.

Sergio Carvalho
  • 251
  • 3
  • 9
  • AFAIK, what you want is not possible. Your components (e.g., activities) need to be in the main classpath, not from some other classloader tied to some other DEX. The Android framework code does not know about those other DEX files and their classloaders -- only your application code does. – CommonsWare Mar 28 '14 at 11:55
  • 1
    Thanks for replying, you said "The Android framework code does not know about those other DEX files and their classloaders -- only your application code does." Maybe there is a way to include the new dex in the DexPathList – Sergio Carvalho Mar 28 '14 at 14:06
  • I'm encountering the same error as well... do you manage to load the activity using your own class loader? – Zennichimaro May 20 '14 at 09:32

1 Answers1

0

It's not possible to reference an activity in a secondary dex. An alternative approach is to extract the activity class file(s) from the jar and place them in another project/jar in your primary dex/apk. It probably won't be easy or even possible in case of complex class hierarchy but in my case the activity had relatively few dependencies and this approach worked.

stan0
  • 11,549
  • 6
  • 42
  • 59
  • Also keep in mind the license of the jar you use - it might forbid messing with the classes and their structure. – stan0 May 15 '15 at 13:04