lastpeony4
lastpeony4

Reputation: 577

Imported Dependency Module Classes are not seen LibGDX inside Android app

I am using libgdx inside an android app as fragment and this is how my project structure looks like: enter image description here

What i am trying to do is call module "app" classes from module "my-gdx-game-core" So that i can communicate between libGDX game and android app.

By the way i can call my-gdx-game-android from app and my-gdx-game-core from my-gdx-game-android. So that i can start game inside android fragment.

Eventhough i added app as dependency to my-gdx-game-core its not seen.Gradle sync is succesfull but i just cant access classes for some reason.Also if i right click "my-gdx-game-core" module and check dependencys from android studio i can see app there.

enter image description here

build.gradle for Project:LibGDXInAndroidKotlin:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    ext.kotlin_version = '1.3.20'

    repositories {
        google()
        jcenter()
        mavenLocal()
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        mavenLocal()
        mavenCentral()
        maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
        maven { url "https://oss.sonatype.org/content/repositories/releases/" }
    }
}

project.ext {
    minSdkVersion = 16
    targetSdkVersion = 28
    compileSdkVersion = 28
    gdxVersion = '1.9.10'
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

build.gradle for Module app

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'


android {
    compileSdkVersion project.compileSdkVersion
    defaultConfig {
        applicationId "com.ersen.androidwithlibgdx"
        minSdkVersion project.minSdkVersion
        targetSdkVersion project.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation project(":my-gdx-game-android")
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "com.android.support:appcompat-v7:28.0.0"
    implementation "com.android.support:design:28.0.0"
    implementation "com.android.support:support-v4:28.0.0"
    implementation "com.android.support.constraint:constraint-layout:1.1.3"
    implementation 'junit:junit:4.12'
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'com.google.android:flexbox:1.0.0'
    implementation 'com.gauravk.bubblenavigation:bubblenavigation:1.0.7'
    implementation 'com.android.volley:volley:1.1.1'
    implementation 'de.hdodenhof:circleimageview:3.0.1'
    implementation 'com.akexorcist:RoundCornerProgressBar:2.0.3'
    implementation 'com.github.anastr:speedviewlib:1.4.0'
    implementation 'com.android.support:cardview-v7:27.0.2'
    implementation 'com.android.support:recyclerview-v7:28.0.0'

    implementation 'android.arch.lifecycle:extensions:1.1.1'
}
repositories {
    mavenCentral()
}

build.gradle for my-gdx-game-android

apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'

android {
    compileSdkVersion project.compileSdkVersion

    defaultConfig {
        minSdkVersion project.minSdkVersion
        targetSdkVersion project.targetSdkVersion
        versionCode 1
        versionName "1.0"
    }

    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

}

configurations { natives }

dependencies {
    implementation project(":my-gdx-game-core")

    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "com.android.support:appcompat-v7:28.0.0"
    api "com.badlogicgames.gdx:gdx-backend-android:${project.gdxVersion}"
    natives "com.badlogicgames.gdx:gdx-platform:${project.gdxVersion}:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-platform:${project.gdxVersion}:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-platform:${project.gdxVersion}:natives-arm64-v8a"
    natives "com.badlogicgames.gdx:gdx-platform:${project.gdxVersion}:natives-x86"
    natives "com.badlogicgames.gdx:gdx-platform:${project.gdxVersion}:natives-x86_64"
    compile "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-armeabi-v7a"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-arm64-v8a"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86"
    natives "com.badlogicgames.gdx:gdx-box2d-platform:$gdxVersion:natives-x86_64"

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}

// called every time gradle gets executed, takes the native dependencies of
// the natives configuration, and extracts them to the proper libs/ folders
// so they get packed with the APK.
task copyAndroidNatives {
    doFirst {
        file("libs/armeabi/").mkdirs()
        file("libs/armeabi-v7a/").mkdirs()
        file("libs/arm64-v8a/").mkdirs()
        file("libs/x86_64/").mkdirs()
        file("libs/x86/").mkdirs()

        configurations.natives.files.each { jar ->
            def outputDir = null
            if (jar.name.endsWith("natives-arm64-v8a.jar")) outputDir = file("libs/arm64-v8a")
            if (jar.name.endsWith("natives-armeabi-v7a.jar")) outputDir = file("libs/armeabi-v7a")
            if(jar.name.endsWith("natives-armeabi.jar")) outputDir = file("libs/armeabi")
            if(jar.name.endsWith("natives-x86_64.jar")) outputDir = file("libs/x86_64")
            if(jar.name.endsWith("natives-x86.jar")) outputDir = file("libs/x86")
            if(outputDir != null) {
                copy {
                    from zipTree(jar)
                    into outputDir
                    include "*.so"
                }
            }
        }
    }
}

tasks.whenTaskAdded { packageTask ->
    if (packageTask.name.contains("package")) {
        packageTask.dependsOn 'copyAndroidNatives'
    }
}

task run(type: Exec) {
    def path
    def localProperties = project.file("../local.properties")
    if (localProperties.exists()) {
        Properties properties = new Properties()
        localProperties.withInputStream { instr ->
            properties.load(instr)
        }
        def sdkDir = properties.getProperty('sdk.dir')
        if (sdkDir) {
            path = sdkDir
        } else {
            path = "$System.env.ANDROID_HOME"
        }
    } else {
        path = "$System.env.ANDROID_HOME"
    }

    def adb = path + "/platform-tools/adb"
    commandLine "$adb", 'shell', 'am', 'start', '-n', '%PACKAGE%/%PACKAGE%.AndroidLauncher'
}
repositories {
    mavenCentral()
}

And here the important one build.gradle for my-gdx-game-core

apply plugin: 'kotlin'

dependencies {
    implementation project(path: ':app', configuration: 'default')

    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation "com.badlogicgames.gdx:gdx:${project.gdxVersion}"
    implementation "com.badlogicgames.gdx:gdx-box2d:$gdxVersion"

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"


}

sourceCompatibility = "1.7"
targetCompatibility = "1.7"
buildscript {
    ext.kotlin_version = '1.3.20'
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
repositories {
    mavenCentral()
}
compileKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
compileTestKotlin {
    kotlinOptions {
        jvmTarget = "1.8"
    }
}

As you see i added

implementation project(path: ':app', configuration: 'default')

and it syncs succesfully.By the way if i add just

implementation project(':app')

gradle throws project not resolved error i dont know what is the difference.

Anyway even i added dependency i cant access classes of module 'app'.

I have already tried invalidate caches restart

Edit::::

GameActivity class inside app which starts my-gdx-game-android's fragment

class GameActivity : AppCompatActivity(), AndroidFragmentApplication.Callbacks {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val libgdxGameFragment:AndroidGameFragment = AndroidGameFragment()




        //never mind if this supportFragmentManager... shows type mismatch error.Its working. this line puts libgdx into fragment.fragment is similar to component in react.
        supportFragmentManager.beginTransaction().replace(R.id.fragment_container, libgdxGameFragment, AndroidGameFragment::class.java.simpleName).commit()


    }




    override fun exit() {

    }
      fun myFun(){

    }
}

AndroidGameFragment inside my-gdx-game-android which starts my-gdx-game-core(actual libgdx game)

class AndroidGameFragment () : AndroidFragmentApplication(){



    


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreateView(inflater, container, savedInstanceState)
        val config = AndroidApplicationConfiguration()




        return initializeForView(MyGdxGame(), config)
    }

 




}

Upvotes: 1

Views: 887

Answers (1)

Tenfour04
Tenfour04

Reputation: 93759

You have a cyclical relationship there...two different modules that are dependent on each other. I don't think that will work.

LibGDX projects are typically set up with a core module that is platform independent, and then android and desktop modules that depend on the the core. This allows you to very rapidly iterate on the desktop without having to compile and install Android builds over and over through most of your development process.

If you truly don't care about the benefits of being able to test on your computer, you don't need a core module at all. You would just put everything into Android. What you're trying to do now effectively defeats the purpose of having a separate core module.

However, I would recommend keeping them separate, in case you ever change your mind or decide to port to other platforms like iOS.

If you need to call android specific code from core, you don't need to depend on the android module. You can create an interface that is passed to your game constructor. For example, if you want to display an Android Toast, you could make an interface like this in core:

public interface PlatformAdapter {
    void showToast(String message);
}

In your game, capture a reference to it from your constructor and call the adapter when you want Android to do something:

private PlatformAdapter adapter;

public MyGame (PlatformAdapter adapter){
    this.adapter = adapter;
}

void showToast(String message){
    if (adapter != null) adapter.showToast(message);
}

Then in your android module, you can pass an adapter into your game. For example:

public class AndroidLauncher extends AndroidApplication implements PlatformAdapter {
    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
        config.r = 8;
        config.g = 8;
        config.b = 8;
        config.a = 8;
        config.useWakelock = true;
        initialize(new MyGame(this), config);
    }

    @Override
    public void showToast(String message){
        runOnUiThread( new Runnable(){ public void run() {
            Toast.makeText(this, message, Toast.LENGTH_SHORT);
        }});
    }
}

Upvotes: 1

Related Questions