I can use android methods from GDX (Platform specific code), but is it possible to get libgdx method from android back-end?
I have firebase database. On android side of my game I catch any changes in database. And I need to transfer that changes to my core back-end (For example update some actors, labels, and so on). What's the best way to do that?
Accessing Platform Specific API inside core module can be possible using Interfacing.
core-module is common part of all platform so you can access anywhere in your project.
Keep reference of ApplicationListener, If you want to call any method/access data member of your core module.
Inside android module :
public class AndroidLauncher extends AndroidApplication {
MyGdxGame gdxGame;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
gdxGame=new MyGdxGame();
initialize(gdxGame, config);
}
public void andoridMethod(){
System.out.println(gdxGame.x); //access data member
gdxGame.doSomething(); //access method
}
}
Inside core module :
public class MyGdxGame implements ApplicationListener {
public int x=4;
public void doSomething(){}
// Life cycle methods of ApplicationListener
}
Good news this is possible and simple, just import whatever you need, for example the Color class from LibGDX
import com.badlogic.gdx.graphics.Color;
public class AndroidLauncher extends AndroidApplication {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
Color color = new Color();
initialize(new Game(), config);
}
Hope this is what you needed
If you simply call core functions from your Android code, as suggested by Aryan, the code will be executed on a different thread, which may cause issues unless you have designed your code to be thread safe.
If you want to make sure it is executed on the Gdx render thread, you should keep a reference to your game in the Android code then use
Gdx.app.postRunnable(new Runnable(){
#Override
public void run(){
gdxGame.doSomething();
}
})
The runnable should then be executed at the start of the render loop (before input processing).
Related
I need to get the Context of my app but in my main Class extends from Game so I can not extends from Activity. Does anybody know how to do it?
Thank you!
LibGDX is a cross-platform game engine, so your application can be executed on multiple platforms. Only Android, which is just one supported platform, can provide a Context object.
To get around this issue, you'll need to create an Interface in the core module of your LibGDX project. That Interface can, for example, contain a getContext() method. Add the interface as an argument in the constructor of your main LibGDX class. In every platform-specific module, you should then implement this Interface , override the getContext() method (by returning a Context object in the android module and null in every other module) and pass it with the constructor for the main LibGDX class in the Launcher class for that module.
For more information about the topic, read the LibGDX Wiki: https://github.com/libgdx/libgdx/wiki/Interfacing-with-platform-specific-code
EDIT:
LibGDX isn't able to handle the Context object, you'll need to manipulate the Context object in the Android module, instead of passing it to the core module! Thanks to #Nicolas and #Luis Fernando Frontanilla for mentioning this.
Interfacing is the way to go since you can't access Android specific code from Core module.
Step 1: Create the interface (CORE MODULE)
public interface MyInterface {
void manipulateContext();
void manipulateContextWithExtraParams(String example, int example2);
}
Step 2: Implement the interface (ANDROID MODULE)
import android.content.Context;
public class InterfaceImplementation implements MyInterface {
private Context context;
public InterfaceImplementation(Context context) {
// Store the context for later use
this.context = context;
}
#Override
public void manipulateContext() {
// Do something with the context, this is called on the core module
System.out.println(context);
}
#Override
public void manipulateContextWithExtraParams(String example, int example2) {
if (example2 == 1) {
System.out.println(example + context);
} else {
System.out.println(example);
}
}
}
Step 3: Send the implemented interface your game (ANDROID MODULE)
import android.os.Bundle;
import com.badlogic.gdx.backends.android.AndroidApplication;
import com.badlogic.gdx.backends.android.AndroidApplicationConfiguration;
import com.frontanilla.helping.getcontext.InterfaceImplementation;
import com.frontanilla.helping.getcontext.MyGame;
public class AndroidLauncher extends AndroidApplication {
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
InterfaceImplementation interfaceImplementation = new InterfaceImplementation(this);
// Here we send the implementation to our Game in Core module
initialize(new MyGame(interfaceImplementation), config);
}
}
Step 4: Store and use the methods you defined on your interface (CORE MODULE)
import com.badlogic.gdx.Game;
public class MyGame extends Game {
private MyInterface myInterface;
public MyGame(MyInterface myInterface) {
// Store for later use
this.myInterface = myInterface;
}
#Override
public void create() {
// Example of manipulating the Android Context indirectly from Core module
myInterface.manipulateContext();
myInterface.manipulateContextWithExtraParams("Hello", 2);
}
}
As you can see, you will not be manipulating the Context from the core module directly, instead, place that logic on the InterfaceImplementation class
What I have tried is:
scoreHelper = new ScoreSQLiteHelper(context,"dbtest",null,1);
db = scoreHelper.getWritableDatabase();
but I don't have any context to feed that method.
It would be usefull any other way to get a path to create the db with:
db = SQLiteDatabase.openOrCreateDatabase(path,null);
I know a good amount of java but this is my first time programming with the android sdk. I need to get the rotation of the phone in real time and display it on the screen. I was wondering what sensor method to use, as I heard that getOrientation was processor intensive and may not work in real time. Secondly, I was wondering which class I'd right this program in, I don't quite understand android class hierarchy yet. Thirdly, how would I make the numbers change on the screen in real time?
Thanks for the help!
I was wondering what sensor method to use, as I heard that getOrientation was processor intensive and may not work in real time.
You'll want to have a look at the OrientationEventListener object.
Secondly, I was wondering which class I'd right this program in, I don't quite understand android class hierarchy yet.
To get you started, you could build all this code into an Activity. Unlike a traditional Java program there is no main() entry point method and you won't user the constructors of application component classes to instantiate them. Lifecycle callback methods like onCreate() and onDestroy() are where you will want to do initialization and teardown of instance information. This guide may help you in how to construct your application to use a single Activity.
Thirdly, how would I make the numbers change on the screen in real time? Thanks for the help!
The OrientationEventListener includes a callback method for each change, simply use this callback to update a view in your UI.
Here is a simple example pulling it all together:
public class OrientationActivity extends Activity {
private OrientationEventListener mListener;
private TextView mTextView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
setContentView(mTextView);
mListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_UI) {
#Override
public void onOrientationChanged(int orientation) {
mTextView.setText(String.valueOf(orientation);
}
};
}
#Override
public void onResume() {
super.onResume();
mListener.enable();
}
#Override
public void onPause() {
super.onPause();
mListener.disable();
}
}
I have a real problem using my app that involve 2 processes. One process its executing a Service (p1) and the other the GUI (p2).
I have a class in p2 that implements the use of an object (iThing) that is custom memory managed (and its static). It has to be like this bacause of Android OS implementation of destroying the views whenever he wants.
public class Connections{
public static int iGlobalCounter=0;
public static Object iThing;
public static void start(){
iGlobalCounter++;
Log.d("PROCESS", "UP: "+iGlobalCounter);
if (iGlobalCounter<=1){
//Create the object "iThing"
}
}
public static int stop(){
iGlobalCounter--;
Log.d("PROCESS", "DOWN: "+iGlobalCounter);
if (iGlobalCounter<=0){
//Destroy the object "iThing"
}
}
}
The main GUI (in p2), starts and stops the variable on the onCreate / onDestroy (for all views in my app)
public class MyMainClass extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Connections.start();
}
#Override
public void onDestroy(){
super.onDestroy();
Connections.stop();
}
}
Finally in p1 I have the service, which also needs the variable, so, it does the same
public class MyMainService extends Service{
#Override
public void onCreate() {
super.onCreate();
Connections.start();
}
#Override
public void onDestroy(){
super.onDestroy();
Connections.stop();
}
}
The problem is that if I use only p2 (GUI), it goes all well, but when I execute the service (in p1), the counter doesn't increment from the last state, but from 0, resulting in destroying the object when leaving the service, not the app.
if do this navigation, I get the following counters:
MyMainClass (1) --> OtherClass (2) --> AnotherClass (3) --> MyMainService (1)
My question is if there is a way of having a multi-process global variable? As it seems that every process takes its own static variables and are not "real static". A solution could be using SharedPreferences to save the state, but not really nice solution, as it hasn't to be saved when leaving the app.
Thanks,
PAU
I think that you should extend Application class and put your globalVariable there.
You can store your global data in shared memory (see MemoryFile).
To synchronize access to the file, I think the best approach is to implement some sort of spinlock using the same memory file.
In and case, I don't know a simply way of doing this.
You have the following options which you can look into for sharing data between different processes,
Message Queue,
Named Pipes,
Memory mapped files
WCF on Named Pipes or MSMQ
I'm working on a Android app which uses the Roboguice dependency injection framework.
So most of the time we extend RoboActivity, RoboListActivity and similar.
Now I would like to introduce some sort of global error handling which will show some alert or a error activity in case the application crashes.
I have done this before by implementing a base activity like this:
public class BaseActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new GeneralError(this));
}
where I define the default exception handler and all other activities then derived from this one.
Now I'm wondering how this is achieved with Roboguice?
Here is some rough psuedo code that should get you started. It uses the roboguice events to make some of these cross cutting concerns a little easier.
public class GlobalErrorHandler {
// injects the current activity here
#Inject Context context;
public void onCreate(#Observes OnCreateEvent e) {
// Wires up the error handling
Thread.setDefaultUncaughtExceptionHandler(new GeneralError(context));
}
}
public class MySpecificActivity {
// required in every activity that needs error handling
#Inject GlobalErrorHandler errorHandler;
}
Is there any way in android to intercept activity method calls (just the standart ones, like "onStart. onCreate")?
I have a lot of functionality that must be present in every activity in my app, and (since it uses different types of activities (List, Preferences)) the only way to do it is to create my custom extensions for every activity class, which sucks :(
P.S. I use roboguice, but since Dalvik doesn't support code generation at runtime, I guess it doesn't help much.
P.S.S. I thought about using AspectJ, but it's too much of a hassle since it requires a lot of complications (ant's build.xml and all that junk)
The roboguice 1.1.1 release includes some basic event support for components injected into a context. See http://code.google.com/p/roboguice/wiki/Events for more info.
For Example:
#ContextScoped
public class MyObserver {
void handleOnCreate(#Observes OnCreatedEvent e) {
Log.i("MyTag", "onCreated");
}
}
public class MyActivity extends RoboActivity {
#Inject MyObserver observer; // injecting the component here will cause auto-wiring of the handleOnCreate method in the component.
protected void onCreate(Bundle state) {
super.onCreate(state); /* observer.handleOnCreate() will be invoked here */
}
}
You could delegate all the repetitive work to another class that would be embedded in your other activities. This way you limit the repetitive work to creating this object and calling its onCreate, onDestroy methods.
class MyActivityDelegate {
MyActivityDelegate(Activity a) {}
public void onCreate(Bundle savedInstanceState) {}
public void onDestroy() {}
}
class MyActivity extends ListActivity {
MyActivityDelegate commonStuff;
public MyActivity() {
commonStuff = MyActivityDelegate(this);
}
public onCreate(Bundle savedInstanceState) {
commonStuff.onCreate(savedInstanceState);
// ...
}
}
This minimalises the hassle and factorises all common methods and members of your activities. The other way to do it is to subclasse all the API's XXXActivty classes :(
Take a look at http://code.google.com/p/android-method-interceptor/, it uses Java Proxies.