Reputation: 577
I am using libgdx inside an android app as fragment and this is how my project structure looks like:
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.
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
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