as far as I understood the Android-NDK-thingy it works as follows: I have to use a NativeActivity that itself calls into the attached native code handing over some OpenGL graphics context. This context can be used by the native part to draw some things with.
What I could not fiddle out until now: how about some GUI elements? Is there a possibility to call back from native code to Java just to create some UI-elements and perhaps to use layouts? Means is it possible to use the standard Android GUI elements also with such native code?
If yes: how can this be done? If not: what alternatives exist (except drawing everything manually)?
Thanks!
If you want to use GUI stuff on the openGL view, I think it would be better to use a normal Activity instead of a NativeActivity.
You can use the Android sample called GL2JNIActivity. Check that to import it from Eclipse.
You can declare some native functions in the JNI Library part (class JNILib in the sample). which you will call when you your GUI listeners get called. Basically it will look like that:
public class GL2JNILib {
static {
// Maybe you need to load other relevant libraries here
System.loadLibrary("gl2jni");
}
public static native void init(int width, int height);
public static native void step();
/*Add here your native functions to send to the native code*/
public static native void buttonClicked();
//... add other listeners here (i.e: screen touched, etc.)
}
Then in the Activity itself (in the sample that corresponds to the class JNIActivity), you can just load an XML GUI file as usual. When you get some input through the GUI, you can just call the native functions added in the GL2JNI class. More or less it will look like that:
public class GL2JNIActivity extends Activity {
GL2JNIView mView;
Button mButton;
#Override protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mView = new GL2JNIView(getApplication());
setContentView(mView);
mButton = (Button)findViewById(R.id.your_button);
mButton.setOnClickListener( new Button.OnClickListener(){
#Override
public void onClick(View v) {
mView.buttonClicked();
}
});
}
/*...*/
}
Finally, you have to implement the native function in the native side:
JNIEXPORT void JNICALL Java_com_android_gl2jni_GL2JNILib_buttonClicked(
JNIEnv * env, jobject obj)
{
// will be called when the button is clicked
}
Related
As the title suggested, How can I call Java function from C++ if the function is from a different java activity class?
All of the sample and tutorials calls C++ function and java back and forth but the caller is the class and the JNIEnv and jobject are passed from java thru JNI. But what if the function that needed to be called is from a different java activity class? How to do this? passing the "this" of the activity did not work
Here is sample layout of classes
Activity class
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
JNIAdapter.launch();
}
private void DisplayLoginDialog()
{
//...
}
}
JNIAdapter.class
public class JNIAdapter {
static {
System.loadLibrary("jnisample-lib");
}
public static native void launch();
}
jnisample.cpp
extern "C"
JNIEXPORT void JNICALL
Java_com_JNIAdapter_launch(JNIEnv *env,jobject object)
{
jclass dataClass = env->FindClass("com/game/ramo/MainActivity");
jmethodID javaMethodRef = env->GetMethodID(dataClass, "DisplayLoginDialog", "()V");
env->CallVoidMethod(object, javaMethodRef);
}
In the above code, using the jobject, refers to the JNIAdapter class and not the Activity hence the DisplayLoginDialog() is not called.
How to do this?
Your small example (I understand that you reduced all details not relevant to the specific problem, that's very nice!) could run without native method. JNIAdaptor.launch() could be pure Java. So, to begin with, rewrite it in Java and make sure it works.
The issues could be that MainActivity.DisplayLoginDialog() may expect its parent activity to be in the foreground, or in some specific state. This is easier to fix in pure Java.
After that, the JNI code you wrote should run without problems.
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).
I am looking to make a game and I need to involve native android sdk features such as toast, dialog, in app billing, other google Api, gcm ..etc
I am pretty experienced with android sdk when I built tools apps and I used animations and very briefly surface view.
However I have looked into libdgx and looks promising but the only downside I find is the "not so easy integration with Android native sdk". Ie, I can't just start my own activity or call native api unless I am missing it
So I was wondering, should I go with libgdx in this case or should I go with the native route?
Thank you
If you're sure you're not going to target other platforms, you can just move your code from the default core project into your Android project and work from there, calling any API as you please. But you would lose the ability to test on desktop.
To maintain portability to other platforms and ability to test on desktop, you can create an interface listing all the Android API methods you would like to call. Pass an instance of this interface into your game's constructor in your Android project, so your game can indirectly call them. Your desktop project can pass in an instance of this interface with empty or system logging methods.
Example:
public class MyGdxGame extends ApplicationAdapter {
public interface AndroidAPIAdapter {
public void makeToast(String msg);
public void startActivity(int activityNumber);
}
AndroidAPIAdapter androidAPIAdapter;
public MyGdxGame (AndroidAPIAdapter androidAPIAdapter){
this.androidAPIAdapter = androidAPIAdapter;
}
//Call this from game code in core project as needed
public void makeToast(String msg){
if (androidAPIAdapter!=null)
androidAPIAdapter.makeToast(msg);
}
//Call thisfrom game code in core project as needed
public void startActivity(int activityNumber){
if (androidAPIAdapter!=null)
androidAPIAdapter.startActivity(activityNumber);
}
//...
}
with:
public class MyGameActivity extends AndroidApplication implements AndroidAPIAdapter {
public static final int ACTIVITY_SETTINGS = 0;
public static final int ACTIVITY_ABOUT = 1;
//etc.
public void onCreate (Bundle bundle) {
super.onCreate(bundle);
AndroidApplicationConfiguration config = new AndroidApplicationConfiguration();
config.useImmersiveMode = true;
initialize(new MyGdxGame(this), config);
}
#Override
public void makeToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT);
}
#Override
public void startActivity(int activityNumber) {
switch (activityNumber){
case ACTIVITY_SETTINGS:
startActivity(this, MySettingsActivity.class);
break;
case ACTIVITY_ABOUT:
startActivity(this, MyAboutActivity.class);
break;
}
}
}
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'm familiar with Java but am just starting out Android programming, and don't really know what I need to make things happen. I'm trying to work with a Canvas, I'm basically making an app that reads real-time data and makes a constantly changing graph based off of it, with some buttons and other interactive UI. What are the methods I need to implement? For example, in "regular" Java, I know I would NEED to have
public void init(){//...}
public void paint(Graphics g) {//...}
public void run(){//...}
public static void main (String argv[]) {//...}
//...and more
Based on sample code that I found it seems like I need the following general outline (plus my own miscellaneous functions and classes).
public class MyClass extends Activity{
public void onCreate(Bundle savedInstanceState){//initialization and setup}
public class MySurfaceView extends SurfaceView implements Runnable{
public MySurfaceView(Context context){//constructor}
public void onResumeMySurfaceView(){//???}
public void onPauseMySurfaceView(){//deal with user leaving the activity}
public void run(){//...}
public boolean onTouchEvent(){//...}
}
}
Do I need all of these? What more/else do I need? And, what goes in each of the methods (e.g., where does the stuff I would normally put in paint(Graphics g) go)?
I realize this is a very general question that's kind of big, and would appreciate either tips or a link to a tutorial that is more specific than, say, http://developer.android.com/reference/android/app/Activity.html
http://www.amazon.com/Hello-Android-Introducing-Development-Programmers/dp/1934356565/ref=sr_1_1?ie=UTF8&qid=1309211182&sr=8-1
I would suggest getting a good book like the one above.