Creating native extensions (android, ios)


#1

Hey,

there is an OpenFl game in which we have to implement 3 SDK. Any decision fits but creating native extensions is the best.

1: https://github.com/tapdaq

2: https://www.heyzap.com/
(We need the following networks and ad formats - Applovin, Chartboost, Facebook, Unity, and Vungle)

3: http://www.gameanalytics.com/docs

There are stencyl extensions -
http://byrobin.nl/store/product/tapdaq-advertising/
http://byrobin.nl/store/product/heyzap-advertising-for-ios-android-stencylopenfl/

Since stencyl is using OpenFl maybe it’s posible to re-code this extensions to work with OpenFl only.

I really appreciate any help you can provide.


#2

Perhaps there’s more information here?

Native extensions for Stencyl would be the same as ordinary Lime/OpenFL native extensions, to my knowledge


#3

I asked the author, and he said that the extension as it is right now, can only use with Stencyl and the extension should be re-code a bite to work with Openfl only. Unfortunately he has no time to help me with my issue, and I have no experience enough to do it myself.


#4

This is the only reference to Stencyl I see in the code, but it seems unused


#5

You are right. Heyzap extension works with OpenFl. At least with android. But I only able to run it with empty project. When I try to use extension with current project the error occurs. Could you tell me how to fix this?

Error -

-dex:
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\bin\classes
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\bin\classes.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\extension-api\bin\classes.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-admob-9.4.0-r2.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-chartboost-6.6.0-r1.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-vungle-4.0.3-r1.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-applovin-6.3.2-r1.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-hyprmx-4.0.1-r3.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\libs\adcolony.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-facebook-4.10.0-r4.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-unityads-2.0.5-r1.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\hyprmx-sdk-internal.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\heyzap-unified-platform-10.2.0.jar
[dex] input: E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\heyzap-ads-sdk-9.6.8.jar
[dex] Pre-Dexing E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\bin\classes.jar -> classes-e950b9491e0c0f29655437bddbb95585.jar
[dex] Pre-Dexing E:\CurrentProjects\megagun\para\bin\android\bin\deps\extension-api\bin\classes.jar -> classes-35827511c58a341484ceb5d828a5ffda.jar
[dex] Using Pre-Dexed fyber-admob-9.4.0-r2-1b7de47526234e09fb5a69b94b93ec20.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-admob-9.4.0-r2.jar
[dex] Using Pre-Dexed fyber-chartboost-6.6.0-r1-fbe12920737b32c8b345366713b64cfa.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-chartboost-6.6.0-r1.jar
[dex] Using Pre-Dexed fyber-vungle-4.0.3-r1-cb235cf6d79373219fbaa6e1384fe57a.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-vungle-4.0.3-r1.jar
[dex] Using Pre-Dexed fyber-applovin-6.3.2-r1-d7ce0f2ca0de223dbf9542f678456d92.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-applovin-6.3.2-r1.jar
[dex] Using Pre-Dexed fyber-hyprmx-4.0.1-r3-5d429de234728702217c365a158a9ade.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-hyprmx-4.0.1-r3.jar
[dex] Using Pre-Dexed adcolony-8d3b2c28a6cab4bb26d24cb2ee63a466.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\libs\adcolony.jar
[dex] Using Pre-Dexed fyber-facebook-4.10.0-r4-65ec0813efa02e3597fc916227b27110.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-facebook-4.10.0-r4.jar
[dex] Using Pre-Dexed fyber-unityads-2.0.5-r1-06ee737e628c3f5136c33ef2bcb06e62.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\fyber-unityads-2.0.5-r1.jar
[dex] Using Pre-Dexed hyprmx-sdk-internal-208a041fa31a138b7568b7ebe7b2fbbd.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\hyprmx-sdk-internal.jar
[dex] Using Pre-Dexed heyzap-unified-platform-10.2.0-ddfeb63242c81bd073c895f9ef23afaf.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\heyzap-unified-platform-10.2.0.jar
[dex] Using Pre-Dexed heyzap-ads-sdk-9.6.8-df00fe5ec1672b127de4b0934037db3d.jar <- E:\CurrentProjects\megagun\para\bin\android\bin\deps\heyzap\libs\heyzap-ads-sdk-9.6.8.jar
[dex] Found Deleted Target File
[dex] Converting compiled files and external libraries into E:\CurrentProjects\megagun\para\bin\android\bin\bin\classes.dex…
[dx]
[dx] UNEXPECTED TOP-LEVEL EXCEPTION:
[dx] com.android.dex.DexException: Multiple dex files define Lcom/heyzap/common/concurrency/AbstractFuture$Sync;
[dx] at com.android.dx.merge.DexMerger.readSortableTypes(DexMerger.java:591)
[dx] at com.android.dx.merge.DexMerger.getSortedTypes(DexMerger.java:546)
[dx] at com.android.dx.merge.DexMerger.mergeClassDefs(DexMerger.java:528)
[dx] at com.android.dx.merge.DexMerger.mergeDexes(DexMerger.java:164)
[dx] at com.android.dx.merge.DexMerger.merge(DexMerger.java:188)
[dx] at com.android.dx.command.dexer.Main.mergeLibraryDexBuffers(Main.java:504)
[dx] at com.android.dx.command.dexer.Main.runMonoDex(Main.java:334)
[dx] at com.android.dx.command.dexer.Main.run(Main.java:277)
[dx] at com.android.dx.command.dexer.Main.main(Main.java:245)
[dx] at com.android.dx.command.Main.main(Main.java:106)
[dx]

BUILD FAILED
C:\Development\Android_SDK\tools\ant\build.xml:888: The following error occurred while executing this line:
C:\Development\Android_SDK\tools\ant\build.xml:890: The following error occurred while executing this line:
C:\Development\Android_SDK\tools\ant\build.xml:902: The following error occurred while executing this line:
C:\Development\Android_SDK\tools\ant\build.xml:283: null returned: 2


#6

Do you need to enable “multi-dex” support for all your extensions to work together?


#7

I’m currently working on a longer response, but I need to respond to this first.

No. The error message didn’t mention either the number “64K,” the number “65536,” or the term “method limit.” Therefore, this isn’t a problem that can be solved using multidex support.


#8

Ugh, this error again. I’ve run into it a bunch of times myself, and it’s pretty annoying.

A little background: “dex” stands for “Dalvik executable,” and a dex file contains compiled Java code. Dalvik was the old runtime environment used on Android (last used in version 4.4). The new version (ART, or Android Runtime) uses the same executable files.

OpenFL apps mostly use C++ code (which is compiled to .so files, not .dex ones), but they do use some Java. OpenFL extensions (like this Heyzap extension) use primarily Java. The app itself produces one dex file, and each extension produces another. Then the build tool merges all of these dex files together into one file, and that one file is what gets run when you launch the app.

Note: a single dex file can have a maximum of 65536 methods (equal to 64 * 1024, hence “64K”). If you hit this limit, you either have to reduce the number of methods (recommended, because you probably aren’t using all of them) or use multiple dex files (not recommended because it slows the build process significantly).

When the dex merger merges the small dex files into a single big one, it looks at method names and signatures. If two methods have different names, then it includes them both. If two methods have the same name but different signatures, that’s fine too, so it includes both. (Java supports method overloading.)

If two methods have the same name and signature (and they’re in the same class), then you have a potential conflict. I believe that this is still fine as long as the contents of the method are the same. If so, then the merger just uses one. But if you have two methods with indistinguishable signatures that do different things, there’s nothing the merger can do, so it throws the “multiple dex files define” error.

What you have to do is figure out which two files define that method, and then either delete one or make them match.

When dealing with the Google Play Services, you can get this error by including different versions. Each piece of the services includes some common methods (the “Google Play Services basement”), and these common methods have changed slightly over time. Therefore, if you include Google+ version 9.2.0 and Google Location services 9.4.0, you get two slightly-different versions of the common methods. The merger can’t reconcile these methods, so it crashes. All you have to do is use the same version of the two, and the error goes away.

Some libraries try to make your life easier by giving you a precompiled jar that you can just “drop in” to your project. That way, you don’t have to bother compiling the actual source. That’s all well and good until the library decides to distribute the jar and the source code in the same download, and you compile the whole thing. Now you have two compiled versions of the library’s code, except they were compiled on different computers, probably using different versions of Java. And the two versions will definitely be very close, but there’s no way they’ll be 100% identical, and so the dex merger will fail. The solution? Just delete that jar.

Sometimes, you can end up doing this to yourself. OpenFL creates an Android project by copying files into your bin/android/bin folder, but if you change the name or location of a file, it won’t delete the old one. This means it’s actually pretty easy to end up with old files alongside new ones, which is an excellent way to cause this error. If this happens, all you need to do is delete bin/android/bin and recompile.

This is one of those hard-to-track-down errors that’s easy to fix once you track it down. The really frustrating part is that the dex merger doesn’t tell you which dex files were in conflict, so you have to guess based on the method in question. In this case, it’s related to Heyzap, so that presumably narrows it down.

If deleting bin/android/bin doesn’t help, download 7-Zip and start looking through your jar files for the AbstractFuture$Sync class. (Also check for Java files named AbstractFuture.) Once you find two of them, take a guess as to which one is safer to delete.


#9

Extension works for Android, but when target iOS the error occurs:
Undefined symbols for architecture i386:
"_GCControllerDidConnectNotification", referenced from:
_SDL_SYS_JoystickInit in liblime.a(06a7fe99_SDL_sysjoystick.o)
_SDL_SYS_JoystickQuit in liblime.a(06a7fe99_SDL_sysjoystick.o)
"_GCControllerDidDisconnectNotification", referenced from:
_SDL_SYS_JoystickInit in liblime.a(06a7fe99_SDL_sysjoystick.o)
_SDL_SYS_JoystickQuit in liblime.a(06a7fe99_SDL_sysjoystick.o)
OBJC_CLASS$_GCController”, referenced from:
objc-class-ref in liblime.a(06a7fe99_SDL_sysjoystick.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)


#10

Have you considered using Enhance as a way to get access to the SDKs you need?

We don’t support everything you are looking for right now but we could look at where the others are on our roadmap and possibly reprioritize some depending on the situation. Send me a message if you’d like to discuss further.


#11

I have fixed error by adding <dependency name="GameController.framework" if="ios"/> Runtime error occurs now, but it is progress)


#12

What version of Lime is this?

Are we missing this tag under the if="ios" section? Is that the issue?


#13

I use 2.9.7 version. But folder “project” is missing, even in latest version of lime, installed through haxelib. This folder is, only if cloning lime from github


#14

Yeah, in order for a change there to take effect, you would need to use Lime from the source, and lime rebuild ios for it to affect the Lime binary


#15

I try Tapdaq on Android (https://github.com/byrobingames/tapdaq), but error occurs:
BUILD FAILED
C:\Development\Android_SDK\tools\ant\build.xml:573: …/google/libs/google-play-services-ads resolve to a path with no project.properties file for project E:\CurrentProjects\megagun\para\bin\android\bin\deps\tapdaq

I found descriptions of a few similar problems in internet, but can’t imagine what to do in OpenFl context.

I use https://github.com/SempaiGames/extension-googleplayservices-basement


#16

There is the reference on the Google ads library: https://github.com/byrobingames/tapdaq/blob/master/dependencies/tapdaq/project.properties.

android.library.reference.2=../google/libs/google-play-services-ads

Since it’s Stencyl extension, reference points to the built-in google-play-services-ads Library of Stencyl engine. This causes an error. I have tried to replace reference:

android.library.reference.2=../google-play-services-ads

but this causes the same error.

I even have tried to replace reference as described in readme.md of extension-googleplayservices-basement:

android.library.reference.2=../google-play-services-basement

But this causes bunch of errors:

...
-compile:
    [javac] Compiling 8 source files to E:\CurrentProjects\megagun\para\bin\android\bin\deps\tapdaq\bin\classes
    [javac] warning: [options] source value 1.5 is obsolete and will be removed in a future release
    [javac] warning: [options] target value 1.5 is obsolete and will be removed in a future release
    [javac] warning: [options] To suppress warnings about obsolete options, use -Xlint:-options.
    [javac] E:\CurrentProjects\megagun\para\bin\android\bin\deps\tapdaq\src\tapdaq\adapters\TMAdMobAdapter.java:8: error: package com.google.android.gms.ads does not exist
    [javac] import com.google.android.gms.ads.*;
    [javac] ^
    [javac] E:\CurrentProjects\megagun\para\bin\android\bin\deps\tapdaq\src\tapdaq\adapters\TMAdMobAdapter.java:36: error: cannot find symbol
    [javac]     private List<InterstitialAd> mInterstitialAd = new ArrayList<InterstitialAd>();
    [javac]                  ^
    [javac]   symbol:   class InterstitialAd
    [javac]   location: class TMAdMobAdapter
    [javac] E:\CurrentProjects\megagun\para\bin\android\bin\deps\tapdaq\src\tapdaq\adapters\TMAdMobAdapter.java:37: error: cannot find symbol
    [javac]     private List<InterstitialAd> mVideoInterstitialAd = new ArrayList<InterstitialAd>();
    [javac]                  ^
    [javac]   symbol:   class InterstitialAd
    [javac]   location: class TMAdMobAdapter
...

BUILD FAILED
C:\Development\Android_SDK\tools\ant\build.xml:597: The following error occurred while executing this line:
C:\Development\Android_SDK\tools\ant\build.xml:716: The following error occurred while executing this line:
C:\Development\Android_SDK\tools\ant\build.xml:730: Compile failed; see the compiler error output for details.

Could you explain, what should be the reference?


#17

Are you using OpenFL 4? If not, switch to this version of Lime so you can use Gradle.

To get started with Gradle, copy this build.gradle file into dependencies/tapdaq, next to project.properties. Finally, install my library, and add this to the extension’s include.xml file:

<set name="google-mobile-ads" />
<haxelib name="google-play-services" />

#18

I can’t install your version of lime properly. First, if I try to clone it from GitHub, I get output:

Cloning into 'lime-2.9.1-gradle'...
remote: Counting objects: 20291, done.
remote: Compressing objects: 100% (6549/6549), done.
remote: Total 20291 (delta 12814), reused 20291 (delta 12814), pack-reused 0
Receiving objects: 100% (20291/20291), 162.62 MiB | 6.11 MiB/s, done.
Resolving deltas: 100% (12814/12814), done.
warning: remote HEAD refers to nonexistent ref, unable to checkout.

and only .git folder is inside lime folder and nothing else.

So, only way I have is installing lime from zip-archive (directly, or using haxelib local). But after that, if I try compile my project, error occurs:

Called from ? line 1
Called from CommandLineTools.hx line 1400
Called from CommandLineTools.hx line 25
Called from CommandLineTools.hx line 126
Called from CommandLineTools.hx line 619
Called from lime/project/PlatformTarget.hx line 70
Called from lime/tools/platforms/AndroidPlatform.hx line 377
Called from lime/tools/helpers/IconHelper.hx line 77
Called from lime/tools/helpers/IconHelper.hx line 393
Called from lime/graphics/Image.hx line 517
Called from lime/graphics/Image.hx line 1278
Called from C:\Development\HaxeToolkit\haxe\std/neko/Lib.hx line 37
Uncaught exception - load.c(237) : Failed to load library : lime.ndll
Build halted with errors.

When i try to call lime rebuild… next error occurs:

Could not find include file "lib/cairo/files.xml"


#19

I may have fixed the “nonexistant HEAD” error; if not, just specify that you want to clone the “develop” branch.

Also, I copied over the NDLL files from Lime 2.9.1 and included tools.n, so now it should be a more user-friendly experience.