Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat
Creating a simple Android plugin - Gideros Forum

Creating a simple Android plugin

gorkemgorkem Maintainer
edited April 2012 in Plugins
This discussion was created from comments split from: Android plugin example.

Comments

  • atilimatilim Maintainer
    edited April 2012
    Hi all,

    First of all, sorry for the late reply. And here are the steps about creating a simple Android plugin:

    Part 1 (build your plugin)
    --------------------
    1. Download the attached zip file and extract to a directory. It contains the sources of BitOp plugin, header files and libgideros.so (for armv6 and armv7) (these files also come with the original Gideros installation).
    2. Also this zip file contains BitOp/jni/Android.mk. This is the makefile of the plugin.
    3. Go to the BitOp directory and execute ndk-build
    4. Now your libbitop.so (for armv6 and armv7) should be ready at BitOp/libs


    Part 2 (create your own Gideros Android Player)
    ---------------------------------------
    1. Create a project with name MyGiderosAndroidPlayer
    2. Without adding any files, export it as an Eclipse project
    3. Delete the directory assets/assets
    4. Deploy it to your device. Now you have a Gideros Andoid Player.

    Part 3 (adding your plugin)
    ----------------------
    1. Copy libbitop.so files to libs directory of MyGiderosAndroidPlayer project
    2. Open your ...Activity.java file and add the line
    System.loadLibrary("bitop");
    under the line System.loadLibrary("gideros");
    3. Deploy it.

    Part 4 (testing your plugin)
    ----------------------
    Test your plugin with this Lua file
    require("bit")
    print(bit.tohex(3133078222))
    please ask if you stuck in any step.

    cheers,

    @techdojo you owe me a coffee :)
    zip
    zip
    BitOp-plugin.zip
    2M
    +1 -1 (+7 / -0 ) Share on Facebook
  • atilimatilim Maintainer
    edited April 2012
    Also I'm attaching the resulting Gideros Android Player with BitOp plugin.
    zip
    zip
    MyGiderosAndroidPlayer.zip
    2M
  • ar2rsawseenar2rsawseen Maintainer
    @atilim oh, I think whole Gideros community owes you much more ;)
    Thank you

    Likes: gorkem

    +1 -1 (+1 / -0 ) Share on Facebook
  • techdojotechdojo Guru
    edited April 2012
    @atilim - the coffee was for Scouser to stop him crying, but this is just for you.

    Likes: gorkem

    Coffee.jpg
    225 x 225 - 12K
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 ) Share on Facebook
  • thanks atilim!!!

    testing now... :)

    Likes: atilim

    TNT ENGiNE for Gideors Studio - Particle Engine, Virtual Pad, Animator Studio, Collision Engine - DOWNLOAD NOW !!! IT'S FREE!!! -
    www.tntengine.com
    +1 -1 (+1 / -0 ) Share on Facebook
  • atilimatilim Maintainer
    @techdojo uhh.. got it now :) anyway, thanks for the coffee. I can share it with @Scouser :P
  • Thanks for the coffee :) and also the plugin howto. I can see where I was going wrong now and hopefully I will get to test it at the weekend.
  • alexzhengalexzheng Guru
    edited April 2012
    Part 4 (testing your plugin)
    do you mean add a lua file to MyGiderosAndroidPlayer and export it again, then run the exported project on device in eclipse?

    Or maybe just create a new gideros project and run it in MyGiderosAndroidPlayer in gideros studio?


  • @alexzheng: As I understand it, you run the new MyGiderosAndroidPlayer.apk as a replacement player on your phone. This player would have your new plugin incorporated.
  • @Scouser
    Maybe any of the above method works,
    the first is necessary for final release and the second is handly for development.
    I will try both when I get home.
  • yes,I have tried both.
    As I undertand, the orignal giderplayer come with gideros studio is just an empty project without asset just like Part 2, when added some asset to it,it will act as a normal app(will not listen for connection),is that right?

    And any tutorial using java code as plugin?
  • chipster123chipster123 Member
    edited April 2012
    @atilim, (and everyone else :) ) what can I read to learn how to get the native android keyboard to pop up and feed me the string when closed? :-B
  • RickyngkRickyngk Member
    edited May 2012
    @atilim
    I see that, we are lacking of some features in bitop example.

    Last few days, I try to write an android plugin which support three functions
    (done)
    + LogI: write down a log message in android console by using __android_log_print
    + GetDeviceModel: get Android device model information (by using android.os.Build.MODEL of Android SDK)
    + Popup an alert if press back key.

    Bitop is good reference for the first one, but not for last twos. I modified some in source to support. And here is my suggests:

    + we could replace/modify default macros REGISTER_PLUGIN. We need to store JavaVM inside plugin to connect to Java side.
    + Support macros for quick connect from JNI to JAVA side.
    + Support Handler in Java-side to handler UI request from JNI (avoid crash by thread)
    + Add an RelativeLayout, instead of add directly mGLView to content-view. By this way, we could add more view into screen (such as admob view).

    My JNI-Java connection template (I used http://stackoverflow.com/questions/9304185/how-to-call-java-function-from-c with some changes)
    void Jni_Todo(....)
    {
        // step 1: Get environment pointer
     
        JNIEnv *env = 0;
        int status;
        int isAttached = 0;
     
        if ((status = (*gJavaVM_guava7androidplugin).GetEnv( (void**)&env, JNI_VERSION_1_6)) < 0)
        {
            if ((status = (*gJavaVM_guava7androidplugin).AttachCurrentThread(&env, NULL)) < 0)
            {
                isAttached = 1;
            }
        }
     
        // step 2: Get JAVA class pointer. For example with Java class  com.gideros.android.MyActivity
     
        jclass cls = (*env).FindClass( "com/giderosmobile/android/MyActivity" );
        if (!cls)
        {
            if (isAttached) (*gJavaVM_guava7androidplugin).DetachCurrentThread();
            return;
        }  
     
        // step 3: Get JAVA function pointer. For example with Java func: static void todo()
     
        jmethodID method = (*env).GetStaticMethodID(cls, "todo", "()V");
        if (!method)
        {
            if (isAttached) (*gJavaVM_guava7androidplugin).DetachCurrentThread();
            return;
        }
     
        //step 4: call java function
        (*env).CallStaticVoidMethod(cls, method); //or others function from  <a href="http://java.sun.com/docs/books/jni/html/fldmeth.html" target="_blank" rel="nofollow">http://java.sun.com/docs/books/jni/html/fldmeth.html</a>
        return;
    }

    Likes: phongtt

    +1 -1 (+1 / -0 ) Share on Facebook
  • I almost understand this 3:-O

    Likes: SatheeshJM

    +1 -1 (+1 / -0 ) Share on Facebook
  • atilimatilim Maintainer
    Hi @Rickyngk,

    About your suggestions,

    1. Totally agree. I'll provide a function so that you can get JavaVM.
    2. Yes, JNI is big and complicated. I'll try to provide macros.
    3. Yes, rendering and executing Lua codes are done on a separate thread. Therefore, any UI action should be run by using the function Activity.runOnUiThread to avoid crashing (And I should emphasize this in the documentation).
    4. Totally agree.

    thanks
    +1 -1 (+3 / -0 ) Share on Facebook
  • @Rickyngk
    Hi,
    Thanks for your JNI template. Can you explain a bit on how to use the template?
    And what exactly is the *gJavaVM_guava7androidplugin pointer?
  • @SatheeshJM: that's just for testing and my code so messy, waiting for official code from @atilim

    About *gJavaVM_guava7androidplugin,
    JavaVM *gJavaVM_guava7androidplugin = 0;
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void *res)
    {
    	gJavaVM_guava7androidplugin = vm;
    	g_registerPlugin(g_pluginMain_guava7androidplugin);
    	return JNI_VERSION_1_6;
    }
    it's a VM pointer, that help me to invoke a java function from C
  • fxonefxone Member

    Part 2 (create your own Gideros Android Player)
    ---------------------------------------
    1. Create a project with name MyGiderosAndroidPlayer
    2. Without adding any files, export it as an Eclipse project
    3. Delete the directory assets/assets
    4. Deploy it to your device. Now you have a Gideros Andoid Player.
    @ar2rsawseen it should be in FAQ section definitely :) it saved my hair :]
  • I cant seem to run the android example project in http://appcodingeasy.com/Gideros-Mobile/Creating-plugins-for-Android-in-Gideros

    I got err on : ENV = g_getJNIEnv(); => function g_getJNIEnv() could not be resolved

  • nevermind this, it seems a bug on Eclipse. The project still can be built although eclipse keeps telling that function could not be resolved
  • I am trying to create Crashlytics plugin for android based on bowerhaus ios version.
    He override the C++ exit function like this :
    void exit(int status)
    {
        // We replace the standard C exit that Gideros calls when it finds a Lua stack error.]
        // First close the stdout file to flush it and the all important stack trace.
        //
        fclose(stdout);
     
        NSString* stdoutString=[NSString stringWithContentsOfFile: getDocPathTo(<a href="/profile/%2Fstdout.txt">@/stdout.txt</a>) encoding:NSUTF8StringEncoding error: NULL];
        NSString* luaStack=distillLuaStackTrace(stdoutString);
     
        // Assign this as a custom key for Crashlytics
        [Crashlytics setObjectValue: luaStack forKey: <a href="/profile/LUASTACK">@LUASTACK</a>];
     
        // Now force a crash
        [[Crashlytics sharedInstance] crash];
     
        // We'll never reach here - this is just to avoid a compiler warning
        for (;;);
    }
    Is stdout.txt file also exist on Android? the point is to be able to grab the Lua error.
  • I think it was also set up by @bowerandy to log the errors

  • @bysreg basically what you should to is to monitor LogCat output for any pattern related to Lua error (this is what @bowerandy is doing in IOS).
    But I actually have not found a way to monitor log output on Android, so it would be possible to save it in separate file.

    Now I don't say there is no way, but currently I did not find any way. Just wanted to note, so you would not spend so much time on it. Sorry :(
  • @ar2rsawseen, what is the difference between Gideros on ios and android that makes t possible to monitor log output on iOS but not on Android?

    Without crash report, it's impossible for me to determine what error the user experienced
  • ar2rsawseenar2rsawseen Maintainer
    edited January 2014
    @bysreg I did not mean that it is related to Gideros, more like related to Android, because monitoring logcat in all seems a bad idea, and I don't even know how it will behave in production (not debug mode).

    And that crash was not reported to console, does not mean it was the Lua error (what you are doing with reading the logs is only related to getting Lua errors)

    But if you insist, this seems to be what you are looking for:
    http://stackoverflow.com/questions/4661234/how-to-constanly-monitor-logcat-file

    ;)
  • @ar2rsawseen,

    I have tried the code in the link and have successfully managed to capture android log. But it seems the root of this problem is that the crash from lua doesnt cause an exception in Android. I tried listening for uncaught exceptions using code from here : http://stackoverflow.com/questions/7370981/how-to-catch-my-applications-crash-report but nothing was caught when there was a lua error

    Is there any specific reason why lua error does not make exception?
  • Yes because it happens on the native side, and not Android Java layer and for now it is implemented, that application exits gracefully.

    So what you could do, is something like this
    In application onDestroy event (when app exits), check the logcat for lua keyword, and if there is something, then save the logs to a file. And then probably on next initialization of app, check if there is anything in the file and create Crashlytics custom exceptions. (or maybe custom exception can work already inside onDestroy method, don't know need to experiment)
  • @ar2rsawseen,

    I could do that. I dont know about the internal of gideros, but i think making an app crash when lua did an error might solve many problems(android would then automatically report that to the developer console).

    but yeah, for the mean time, i will have to make do with that.
Sign In or Register to comment.