I am currently considering porting a app that I start developping with react-native to codenameone. For this, I am still checking the feasability and the amount of work it would requiere (as I would have to port or developp some native library binding from react-native to codenameone because codenameone miss some of my needs, like socket.io support for example). The free codenameone build cloud service beeing limited to app of 1Mb, I have to make my test builds locally (with only a few test classes and the use of the google maps cn1lib, my test app is already above the 1Mb limit) Sadly, there is no free documentation on codenameone on how to perform local builds and actually I couldn't find any instructions on internet on how to do it (I only found, on a blog post, some basic and deprecated instructions on how to perform a local iOS build but nothing for Android). So I had to figure it out myself... After some time spent digging into gradle configuration parametters, I finally succeed into building a basic codenameone app localy that works on my android test device. But the problem is that, when I add an external cn1lib (the google maps native cn1lib https://github.com/codenameone/codenameone-google-maps ), my app bug when oppening a screen that depends from this lib. In the android error log, I could find this message:
D/MyApplication( 551): [EDT] 0:0:0,99 - Exception: java.lang.ClassCastException - com.codename1.googlemaps.InternalNativeMapsImpl cannot be cast to com.codename1.system.NativeInterface
W/System.err( 551): java.lang.ClassCastException: com.codename1.googlemaps.InternalNativeMapsImpl cannot be cast to com.codename1.system.NativeInterface
W/System.err( 551): at com.codename1.system.NativeLookup.create(Unknown Source)
W/System.err( 551): at com.codename1.googlemaps.MapContainer.<init>(MapContainer.java:171)
W/System.err( 551): at com.codename1.googlemaps.MapContainer.<init>(MapContainer.java:151)
W/System.err( 551): at com.tbdlab.testapp.MyApplication.start(MyApplication.java:207)
W/System.err( 551): at com.tbdlab.testapp.MyApplicationStub.run(MyApplicationStub.java:183)
W/System.err( 551): at com.codename1.ui.Display.processSerialCalls(Unknown Source)
W/System.err( 551): at com.codename1.ui.Display.mainEDTLoop(Unknown Source)
W/System.err( 551): at com.codename1.ui.RunnableWrapper.run(Unknown Source)
W/System.err( 551): at com.codename1.impl.CodenameOneThread$1.run(Unknown Source)
W/System.err( 551): at java.lang.Thread.run(Thread.java:818)
I don't really understand why InternalNativeMapsImpl could not be cast into NativeInterface as I looked into the dex file of my compiled apk and all the necessary classes (for android) from the google maps cn1lib are correctly included (So I have com.codenameone.googlemaps.InternalNativeMaps
, com.codenameone.googlemaps.InternalNativeMapsImpl
and com.codenameone.googlemaps.MapContainer
) and so are the codenameone native interface classes they depend on (com.codename1.system.NativeInterface
, com.codename1.impl.android.LifecycleListener
...). And I decompilled them and the code is correct (I do not use any obfuscation method anyway so there is no real reason why the compiled code would have differ from the source code). There is probably something that I am missing here to make a local codenameone build with the usage of a cn1lib.
So has anyone already succeed into making a local build with the usage of a cn1lib that perform native bindings? If yes, what is the exact procedure? I really hope someone would be able to help, because, at this point, I am seriously considering to stick with react-native (which I am quite pleased with, exept the fact that it is not completely native) or to jump into flutter (or kotlin native) even if I still think codenameone offers many advantages over these other solutions (but not beeing able to perform local builds during the development phase is just a complete no-go for me)