x

Search in
Sort by:

Question Status:

Search help

  • Simple searches use one or more words. Separate the words with spaces (cat dog) to search cat,dog or both. Separate the words with plus signs (cat +dog) to search for items that may contain cat but must contain dog.
  • You can further refine your search on the search results page, where you can search by keywords, author, topic. These can be combined with each other. Examples
    • cat dog --matches anything with cat,dog or both
    • cat +dog --searches for cat +dog where dog is a mandatory term
    • cat -dog -- searches for cat excluding any result containing dog
    • [cats] —will restrict your search to results with topic named "cats"
    • [cats] [dogs] —will restrict your search to results with both topics, "cats", and "dogs"

How to use Android Java .aar library?

I googled this quite a bit, but came out empty handed. There were some links but those related to source code version of UE. Before going down that path I decided to asks here whether there is some simple way to add and access an .aar library in my UE 4.20 Android project?

I found this announcement telling that aar files can be registered e.g. in aar-imports.txt. It continues about gradle files, but it remains a bit unclear whether something more needs to be added there or not. I really wish there were a solid document about using .aar files!

Based on some forum advice, I inserted my lib into aar-imports.txt file, like this

 repositories $(ANDROID_HOME)/extras
 repositories $(ENGINEDIR)/Source/ThirdParty/Android/extras
 com.google.android.gms,play-services-auth,11.8.0
 com.google.android.gms,play-services-games,11.8.0
 com.google.android.gms,play-services-nearby,11.8.0
 com.google.android.gms,play-services-plus,11.8.0
 com.mycompany.myproduct.mylib,mylib-release,1.0
 

and inserted the lib under C:\NVPACK\android-sdk-windows\extras\m2repository\com\mycompany\myproduct\mylib\mylib-release\1.0\mylib-release-1.0.aar, together with a handmade POM file.

POM file:

 <project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>1.0</modelVersion>
     <groupId>com.mycompany.myproduct.mylib</groupId>
     <artifactId>mylib-release</artifactId>
     <version>1.0</version>
     <packaging>aar</packaging>
 </project>

I also added the following lines into gradle.properties file in the Android Studio:

     POM_NAME=mylib-release
     POM_ARTIFACT_ID=mylib-release
     POM_PACKAGING=aar

Although I am not sure are these necessary or not.

It seems that this way the file is included into the build. At least the Unreal launch complained over wrong paths until I got them right.

To get forward I should now make AndroidThunkJava_* methods for all my library public static methods, I think.

Should I make a class similar to AndroidJNI.*, except for my own library only? Or should I add my own library methods into AndroidJNI class? And where to put these files (in same place as AndroidJNI or somewhere in my own project structure)?

Product Version: UE 4.20
Tags:
more ▼

asked Oct 03 '18 at 09:22 AM in C++ Programming

avatar image

Teleporno
17 4 4 9

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

2 answers: sort voted first

I solved this by simply pulling the .jar out of the .aar package. .jar works without problems, and luckily I did not need any resources from .aar.

more ▼

answered Apr 11 '19 at 12:29 PM

avatar image

Teleporno
17 4 4 9

avatar image Burnrate Jun 24 '19 at 12:58 PM

How did you include the .jar in the project? Through the build.cs or other? Can you post exactly what you did?

Thank you.

(comments are locked)
10|2000 characters needed characters left
Viewable by all users

If by "simple" you mean without playing with C++ then no, you need to brige code from Java to C++ in order to allow UE4 to use it, or else you use already existing APIs and only modify java portion, but i don't of any library that this would be sufficient.

The Java portion of UE4 is inside /Build/Android you can extend or modify that code by placing extra stuff in your project in that location, so you add aar library same way as you would do in any other andorid project. But thats not enough, in order for that library to be usable in UE4 you need to bind it in C++ and potentially create some blueprint nodes if you want to. For that you need to create extra classes in C++ (you can do that in project or plugin, where no need to modify engine source code), to check how to do it look up AndroidJNI in engine source code:

https://github.com/EpicGames/UnrealEngine/tree/f509bb2d6c62806882d9a10476f3654cf1ee0634/Engine/Source/Runtime/Launch/Public/Android

more ▼

answered Oct 03 '18 at 12:59 PM

avatar image

Shadowriver
37.3k 936 172 1116

avatar image Teleporno Oct 04 '18 at 09:19 AM

Thanks you for your answer! By "simple" I meant without modifying the engine code. Wishful thinking, I am afraid :).

Could you open this a bit "so you add aar library same way as you would do in any other android project". This is my first UE Android project, so I have no idea how it is normally done. What folder shall I drop the .aar, which build files to modify to get it included?

avatar image Shadowriver Oct 05 '18 at 02:34 PM

As you see you dont need to modify :) just add files to java directory. by Android i mean project without UE4, Android applicaiton in general since aar fiels is android features

avatar image Teleporno Oct 05 '18 at 09:20 AM

I updated the question with current status. I think I got the library in the build now.

avatar image Shadowriver Oct 05 '18 at 02:36 PM

Just add class in wither plugin or game project code and do what AndroidJNI does

avatar image Teleporno Oct 09 '18 at 05:48 AM

I am still not sure where I shall place the new MyLibJNI.cpp and MyLibJNI.h files (MyLibJNI is my new JNI interface c++ class with AndroidThunkJava calls).

Somewhere in my Unreal project folders?

Or the same place as AndroidJNI.* classes are, i.e. C:\UE42\UnrealEngine\Engine\Source\Runtime\Launch\Public\Android\AndroidJNI.h ?

avatar image Chris Babcock STAFF Oct 10 '18 at 04:59 PM

The best thing to do here would be to make a plugin that uses a UPL xml file to add the AAR dependency and to contain your functions instead of placing your code into the engine itself. Or, if this will just be for your C++ project you can just place the code there.

     <buildGradleAdditions>
         <insert>
 dependencies {
     implementation('com.mycompany.myproduct.mylib:mylib-release:1.0')
 }
         </insert>
     </buildGradleAdditions>
 

To use the AndroidJNI code in your code you just need to put in a private dependency on Launch module to have the include paths available: You can do this in the Build.cs like this:

 PrivateDependencyModulesNames.Add("Launch");

Then you'd want to include this in your code that uses JNI:

 #include "Android/AndroidJNI.h"
 #include "Android/AndroidApplication.h"

Then if you had a Java function like this:

 void AndroidThunkJava_MyCode_SetIntegerKey(String Key, int Value)

you could call it like this:

 void FMyModule::SetIntegerKey(const FString& Key, int32 Value)
 {
     if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
     {
         static jmethodID SetIntegerKeyMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_MyCode_SetIntegerKey", "(Ljava/lang/String;I)V", false);
 
         jstring KeyJava = Env->NewStringUTF(TCHAR_TO_UTF8(*Key));
         FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, SetIntegerKeyMethod, KeyJava, Value);
         Env->DeleteLocalRef(KeyJava);
     }
 }







avatar image Teleporno Oct 11 '18 at 02:02 PM

I made a plugin named AndroidLib. I did not find any suitable UPL example, but I hacked together this from some old APLs and UPLs that I found:

 <?xml version="1.0" encoding="utf-8"?>
 <root xmlns:android="http://schemas.android.com/apk/res/android">
     <trace enable="true"/>
     <init>
         <log text="AndroidLib init"/>        
     </init>
 
   <AARImports>
     <insertValue value="repository $S(PluginDir)/../../ThirdParty/repository"/>
     <insertNewline/>
         <insert>com.MyCompany.MyProduct.MyLib,MyLib-release,1.0</insert>
     <insertNewline/>
   </AARImports>
   
   <buildGradleAdditions>
     <insert>
       dependencies {
         implementation('com.MyCompany.MyProduct.MyLib:MyLib-release:1.0')
       }
     </insert>
   </buildGradleAdditions>
 
   <!-- optional additions to the GameActivity imports in GameActivity.java -->
   <gameActivityImportAdditions>
     <insert>
     </insert>
   </gameActivityImportAdditions>
 
   <!-- optional additions to proguard -->
   <proguardAdditions>
     <insert>
       <![CDATA[
       -keepattributes Signature
       -dontskipnonpubliclibraryclassmembers
 
      -keepclassmembers class com.epicgames.ue4.GameActivity {
             public <methods>;
             public <fields>;
      }
     ]]>
     </insert>
   </proguardAdditions>

Does this UPL seem correct?

I dropped MyLib-release.aar into the path:

 E:/Unreal Projects/MyProject/Plugins/AndroidLib/ThirdParty/repository/MyLib-release.aar

I also added PrivateDependencyModulesNames.Add("Launch"); into MyProject.Build.cs file

Could not test the actual connection today, launching to device takes so long I have to run :(

avatar image Burnrate Jun 24 '19 at 01:57 PM

Can you use the buildGradleAdditions to add remote dependencies?

Would you be able to add the repositories the same way (how)?

Is the you used placed in the .xml file that is included in the build.cs?

If it is not remote where would you put the .aar and .jar files so they would be included? Can you define where they are?

avatar image Teleporno Oct 12 '18 at 07:34 AM

To test the lib connection, I created an Actor based class "AThirdActor", intantiated that in scene, and placed a call into BeginPlay() to

 public static void createLibManagerInstance()

method in the .aar library

header:

 // Fill out your copyright notice in the Description page of Project Settings.
 
 #pragma once
 
 #include "CoreMinimal.h"
 #include "GameFramework/Actor.h"
 
 #include "ThirdActor.generated.h"
 
 UCLASS()
 class MYLIBUNREALEXAMPLE_API AThirdActor : public AActor
 {
     GENERATED_BODY()
     
 public:    
     // Sets default values for this actor's properties
     AThirdActor();
 
 protected:
     // Called when the game starts or when spawned
     virtual void BeginPlay() override;
 
 public:    
     // Called every frame
     virtual void Tick(float DeltaTime) override;
 
     void CreateLibInstance();
 
 };
 

cpp:

 #include "ThirdActor.h"
 
 #ifdef USE_ANDROID_JNI
 #include "Android/AndroidJNI.h"
 #include "Android/AndroidApplication.h"
 #endif
 
 AThirdActor::AThirdActor()
 {
     PrimaryActorTick.bCanEverTick = true;
 
 }
 
 void AThirdActor::BeginPlay()
 {
     Super::BeginPlay();
     
     CreateLibInstance();
 }
 
 void AThirdActor::Tick(float DeltaTime)
 {
     Super::Tick(DeltaTime);
 
 }
 
 void AThirdActor::CreateLibInstance()
 {
 #ifdef USE_ANDROID_JNI
     if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
     {
         static jmethodID CreateLibManagerInstanceMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "createLibManagerInstance", "()V", false);
         FJavaWrapper::CallVoidMethod(Env, FJavaWrapper::GameActivityThis, CreateLibManagerInstanceMethod);
     }
 #endif
 }
 
avatar image Teleporno Oct 12 '18 at 07:42 AM

This resulted into following error when Launched into device

 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : Failed to find Method
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : [2018.10.12-07.15.29:005][  0]Assertion failed: Method != 0 [File:E:\UE42\UnrealEngine\Engine\Source\Runtime\Launch\Private\Android\AndroidJNI.cpp] [Line: 203]
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : Failed to find Method
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : LogAndroid: Error: === Critical error: ===
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : [2018.10.12-07.15.29:005][  0]LogAndroid: Error: === Critical error: ===
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : LogAndroid: Error:
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : [2018.10.12-07.15.29:005][  0]LogAndroid: Error:
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : LogAndroid: Error: Assertion failed: Method != 0 [File:E:\UE42\UnrealEngine\Engine\Source\Runtime\Launch\Private\Android\AndroidJNI.cpp] [Line: 203]
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : [2018.10.12-07.15.29:005][  0]LogAndroid: Error: Assertion failed: Method != 0 [File:E:\UE42\UnrealEngine\Engine\Source\Runtime\Launch\Private\Android\AndroidJNI.cpp] [Line: 203]
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : LogAndroid: Error: Failed to find Method
 LogPlayLevel:   10-12 10:15:29.005 18659 18694 D UE4     : [2018.10.12-07.15.29:005][  0]LogAndroid: Error: Failed to find Method


Obviously FindMethod does not find the method. But why?

avatar image Teleporno Oct 12 '18 at 10:03 AM

Looking at the proposed codeline

 static jmethodID SetIntegerKeyMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_MyCode_SetIntegerKey", "(Ljava/lang/String;I)V", false);

It seems that it is looking the method from FJavaWrapper::GameActivityClassID class, which seems to be the GameActivity.java class. So should I add something there as well?

I think my question is that should I add features to GameActivity class, namely including my .aar calls there, OR can I access MyLibClass (in the .aar) and its methods directly in the AndrodJNI, like this

     static jmethodID SetIntegerKeyMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::MyLibClassID, "AndroidThunkJava_MyCode_SetIntegerKey", "(Ljava/lang/String;I)V", false);    
   

In AndroidJNI there is this kind of calls

 jclass localGameActivityClass = FindClass(Env, "com/epicgames/ue4/GameActivity", bIsOptional);

Can this FindClass be used to find MyLibClass in the .aar?

avatar image Teleporno Oct 12 '18 at 01:44 PM

I made another test, trying to import the com.mycompany.myproduct.mylib.MyLib class into GameActivity.java.template, and added the "thunk methods" there, but this produces the following error

 LogPlayLevel: :permission_library:compileDebugJavaWithJavac
 LogPlayLevel: :permission_library:transformClassesAndResourcesWithPrepareIntermediateJarsForDebug
 LogPlayLevel: :app:javaPreCompileDebug
 LogPlayLevel: :app:compileDebugJavaWithJavacZ:\app\src\main\java\com\epicgames\ue4\GameActivity.java:120: error: package com.mycompany.myproduct.mylib does not exist
 LogPlayLevel: import com.mycompany.myproduct.mylib.MyLib;
 LogPlayLevel:                            ^
 LogPlayLevel: Z:\app\src\main\java\com\epicgames\ue4\GameActivity.java:2700: error: cannot find symbol
 LogPlayLevel:         MyLib.createLibManagerInstance();
 LogPlayLevel:         ^
 LogPlayLevel:   symbol:   variable MyLib
 LogPlayLevel:   location: class GameActivity

This seems like my UPL does not work properly, as the library is not found.

avatar image Chris Babcock STAFF Oct 12 '18 at 07:01 PM

UPL is fine; it is likely an issue with the embedded package path in the AAR not resolving.

If you want to skip GameActivity, you can just find your method using your own class. You will need to make a GlobalRef or the method will not be stable (would have to do this on every call):

Do this on initializing and store globalMyClass:

 JNIEnv* Env = FAndroidApplication::GetJavaEnv()
 jclass localMyClass = FindClass(Env, "com/mycompany/myproduct/mylib", false);
 jclass globalMyClass = (jclass)Env->NewGlobalRef(localMyClass);
 Env->DeleteLocalRef(localMyClass);
avatar image Teleporno Oct 15 '18 at 07:49 AM

Tried that, and it resulted into this

     : Assertion failed: Class != 0 [File:E:/UE42/UnrealEngine/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp] [Line: 197]
     : Failed to find Class
     : [2018.10.15-07.04.10:830][  0]Assertion failed: Class != 0 [File:E:/UE42/UnrealEngine/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp] [Line: 197]
     : Failed to find Class
     : LogAndroid: Error: === Critical error: ===
 : [2018.10.15-07.04.10:830][  0]LogAndroid: Error: === Critical error: ===
 : LogAndroid: Error:
 : [2018.10.15-07.04.10:830][  0]LogAndroid: Error:
 : LogAndroid: Error: Assertion failed: Class != 0 [File:E:/UE42/UnrealEngine/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp] [Line: 197]
 : [2018.10.15-07.04.10:830][  0]LogAndroid: Error: Assertion failed: Class != 0 [File:E:/UE42/UnrealEngine/Engine/Source/Runtime/Launch/Private/Android/AndroidJNI.cpp] [Line: 197]
 : LogAndroid: Error: Failed to find Class
 : [2018.10.15-07.04.10:830][  0]LogAndroid: Error: Failed to find Class
 : LogAndroid: Error: [Callstack] 0x00000000C36BF5A8 (0x000000000301F5A8) libUE4.so!StaticFailDebug(char16_t const*, char const*, int, char16_t const*, bool)  []
 ...
 : LogAndroid: Error: [Callstack] 0x00000000C2E4D298 (0x00000000027AD298) libUE4.so!FJavaWrapper::FindClass(_JNIEnv*, char const*, bool)  []
 ...
 

I have a feeling that something is wrong in the config/paths/gradle/manifest/... but have no clue what!?

avatar image Teleporno Oct 16 '18 at 04:31 AM

In ADB I get the following error msg:

 : signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------
 : Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI CallVoidMethodV called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.mycompany.myproduct.mylib.MyLibClass" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib, /system/vendor/lib, /system/lib, /system/vendor/lib]]'
 
avatar image Teleporno Oct 16 '18 at 12:39 PM

I created a minimal Unreal project with an aar plugin and pushed it into git. It is obviously a not-yet-working version. If someone finds a cause for crashing, please let me know.

https://github.com/perza/SimpleUnrealAar

(comments are locked)
10|2000 characters needed characters left
Viewable by all users
Your answer
toggle preview:

Up to 5 attachments (including images) can be used with a maximum of 5.2 MB each and 5.2 MB total.

Follow this question

Once you sign in you will be able to subscribe for any updates here

Answers to this question