Announcement

Collapse
No announcement yet.

Using AAR in Android project

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Using AAR in Android project

    I've gone into Unreal/Build/Android/Java/aar-imports.txt and added my aar like so:
    Code:
    com.google.android.gms,kt-bridge,11.0.4
    (for now I'm just using com.google.android.gms for testing purposes)

    I also know that its properly being packaged into my apk because in my output log I'm getting:
    Code:
    UATHelper: Packaging (Android (ASTC)): Extracting AAR kt-bridge-11.0.4
    ...
    UATHelper: Packaging (Android (ASTC)): Updating project.properties, local.properties, and build.xml for kt-bridge-11.0.4...
    now in my code I would like to get the aar and call the method "getInstance".

    I've included in my .h file:
    "Android/AndroidJNI.h" and "Android/AndroidApplication.h"

    and in my .cpp I do:
    Code:
    #if PLATFORM_ANDROID
    if (JNIEnv* Env = FAndroidApplication::GetJavaEnv())
    {
         jclass foundClass = Env->FindClass("com/google/android/gms/kt-bridge");
         if (foundClass)
              return "found class";
    
         return "did not find class";
    }
    #endif
    which results in:
    Code:
    Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI NewStringUTF called with pending exception java.lang.ClassNotFoundException: Didn't find class "com.google.android.gms.kt-bridge" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib, /vendor/lib, /system/lib, /vendor/lib]]'
    I'm not really sure what I'm doing wrong and can't seem to find any useful help online.

    #2
    While aar-imports.txt does still work, the better way is to have your game's Build.cs register a UPL file to add a dependency block to the build.gradle. The UPL would be something like this:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <root xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- init section is always evaluated once per architecture -->
    <init>
    </init>
    
    <buildGradleAdditions>
    <insert>
    dependencies {
    implementation('com.google.android.gms,kt-bridge,11.0.4')
    }
    </insert>
    </buildGradleAdditions>
    
    </root>
    As for the failure to find the class, you should use the AndroidJavaEnv::FindJavaClass("com/google/android/gms/kt-bridge") instead since it uses the proper ClassLoader. Use AndroidJavaEnv::FindJavaClassGlobalRef() if you need to keep a global reference.

    Comment


      #3
      Hey Chris. I decided to take your advice and use UPL.

      My XML file:
      Code:
      <?xml version="1.0" encoding="utf-8"?>
      <root xmlns:android="http://schemas.android.com/apk/res/android">
      <init>
      <log text="KT Bridge"/>
      </init>
      <resourceCopies>
      </resourceCopies>
      <!-- AAR dependencies -->
      <AARImports>
      <insertValue value="com.kt.supervrgame.unityplugin,Bridge,11.0.4" />
      <insertNewline/>
      </AARImports>
      <gameActivityImportAdditions>
      <insert>
      import com.kt.supervrgame.unityplugin.Bridge;
      </insert>
      </gameActivityImportAdditions>
      <gameActivityClassAdditions>
      <insert>
      private Bridge KTBridge;
      public Bridge getKTBridge() { return KTBridge; }
      
      public String AndroidThunkJava_KTBridge_Init()
      {
          String result = "Failed";
          if (KTBridge != null)
          {
              KTBridge.init(App.getContext());
              result = KTBridge.checkAuthenticate();
          }
      
          return result;
      }
      </insert>
      </gameActivityClassAdditions>
      <gameActivityOnCreateAdditions>
      <insert>
      KTBridge = Bridge.getInstance();
      </insert>
      </gameActivityOnCreateAdditions>
      </root>
      and the CPP:
      Code:
      static jmethodID KTBridgeMethod = FJavaWrapper::FindMethod(Env, FJavaWrapper::GameActivityClassID, "AndroidThunkJava_KTBridge_Init", "()Ljava/lang/String;", bIsOptional);
      
      jstring jsString = (jstring)FJavaWrapper::CallObjectMethod(Env, FJavaWrapper::GameActivityThis, KTBridgeMethod);
      const char* nativeName = Env->GetStringUTFChars(jsString, NULL);
      FString ResultName = FString(nativeName);
      Is this correct?
      No matter what string I try to return I always get the following error using logcat:
      Code:
      Abort message: 'java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI GetStringUTFChars called with pending exception java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Application.getApplicationContext()' on a null object reference'
      I need it to return a string because authenticate returns json.

      EDIT: In case someone sees this in the future I fixed it. My issue was with getting the app context incorrectly. My final code looks exactly like what is listed above but instead of "KTBridge.init(App.getContext());" I now have "KTBridge.init(getWindow().getDecorView().getRootView().getContext());"
      Last edited by NotSoCasualGamer; 06-30-2020, 01:34 PM.

      Comment

      Working...
      X