NDK Newbie Getting Started


Last Updated:

  1. paulscode

    paulscode Well-Known Member This Topic's Starter

    Joined:
    Mar 18, 2010
    Messages:
    86
    Likes Received:
    14
    I have a (possibly overly) ambitious goal of writing an N64 emulator to sell on the Android market. I have a great deal of current experience programming in Java, and past experience in C++ (I'm a bit rusty, but its like riding a bike ... I hope ;) ). I have a little bit of experience writing for the Android with the Android SDK and ADT plug-in for Eclipse ... I've written 3 simple starter apps, my most recent being an animated-texture cube app.

    Anyway, my next step is to learn how to compile native C++ code, access it in the Java portion, debug it, etc. I've installed and set up the NDK and Sequoyah in Eclipse, and I'm trying to write a basic "Hello World" app that generates a string in native code and displays it in a basic TextView. The project seems to be set up correctly, it has generated the jni folder with a .cpp and a .mk file inside. I edited the HelloAndroid.cpp File as follows:

    Code (Text):
    1. #include <string.h>
    2. #include <jni.h>
    3.  
    4. extern "C"
    5. {
    6.     jstring Java_paulscode_android_helloandroid_HelloAndroid_sayHi( JNIEnv* env, jobject obj )
    7.     {
    8.         return env->NewStringUTF( "Howdy, this is JNI!" );
    9.     }
    10. }
    11.  
    Then I edited the HelloAndroid.java File as follows:

    Code (Text):
    1. package paulscode.android.helloandroid;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5. import android.widget.TextView;
    6.  
    7. public class HelloAndroid extends Activity
    8. {
    9.     @Override
    10.     public void onCreate( Bundle savedInstanceState )
    11.     {
    12.         super.onCreate( savedInstanceState );
    13.         TextView tv = new TextView( this );
    14.         tv.setText( sayHi() );
    15.         setContentView( tv );
    16.     }
    17.    
    18.     public native String sayHi();    
    19. }
    The project compiles fine, but it fails to run in the AVD, generating the message "Sorry! The application Hello, Android (process paulscode.android.helloandroid) has stopped unexpectedly. Please try again."

    Is there anything obviously wrong with my code, or are there some Eclipse or AVD settings that I need to check? Let me know if you require any further information about this Hello Android project to help me solve the problem.
     

    Advertisement
  2. GIR

    GIR Well-Known Member

    Joined:
    Feb 14, 2010
    Messages:
    96
    Likes Received:
    10
  3. paulscode

    paulscode Well-Known Member This Topic's Starter

    Joined:
    Mar 18, 2010
    Messages:
    86
    Likes Received:
    14
    Thanks for the tip. I'll use your suggestion here to figure out where the crash is occurring.

    Ultimately, I will be using Sequoyah for debugging through Eclipse (allowing me to stop at break points in the code). But before I try to figure any of that out, I'll see if I can get this simple Hello World app to work first so I'm not trying to figure out two things at once.
     
  4. paulscode

    paulscode Well-Known Member This Topic's Starter

    Joined:
    Mar 18, 2010
    Messages:
    86
    Likes Received:
    14
    Ok, I altered the HelloAndroid.java to add in some logging:
    Code (Text):
    1. package paulscode.android.helloandroid;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5. import android.widget.TextView;
    6. import android.util.Log;
    7.  
    8. public class HelloAndroid extends Activity
    9. {
    10.     @Override
    11.     public void onCreate( Bundle savedInstanceState )
    12.     {
    13.         Log.e( "HelloAndroid.onCreate()", "Before super()" );        
    14.         super.onCreate( savedInstanceState );
    15.         Log.e( "HelloAndroid.onCreate()", "Before new TextView" );        
    16.         TextView tv = new TextView( this );
    17.         Log.e( "HelloAndroid.onCreate()", "Before call to native sayHi()" );
    18.         String message = sayHi();
    19.         Log.e( "HelloAndroid.onCreate()", "sayHi() SUCCESS!  Before setText()" );                
    20.         tv.setText( message );
    21.         Log.e( "HelloAndroid.onCreate()", "Before setContentView()" );                
    22.         setContentView( tv );
    23.         Log.e( "HelloAndroid.onCreate()", "COMPLETE!" );                
    24.     }
    25.    
    26.     public native String sayHi();    
    27. }
    Then I ran DDMS, and got the following output from logcat:
    Code (Text):
    1. I/ActivityManager(   60): Starting activity: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=paulscode.android.helloandroid/.HelloAndroid }
    2. I/ActivityManager(   60): Start proc paulscode.android.helloandroid for activity paulscode.android.helloandroid/.HelloAndroid: pid=293 uid=10032 gids={1015}
    3. E/HelloAndroid.onCreate()(  293): Before super()
    4. E/HelloAndroid.onCreate()(  293): Before new TextView
    5. E/HelloAndroid.onCreate()(  293): Before call to native sayHi()
    6. W/dalvikvm(  293): No implementation found for native Lpaulscode/android/helloandroid/HelloAndroid;.sayHi ()Ljava/lang/String;
    7. D/AndroidRuntime(  293): Shutting down VM
    8. W/dalvikvm(  293): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
    9. E/AndroidRuntime(  293): FATAL EXCEPTION: main
    10. E/AndroidRuntime(  293): java.lang.UnsatisfiedLinkError: sayHi
    11. E/AndroidRuntime(  293):     at paulscode.android.helloandroid.HelloAndroid.sayHi(Native Method)
    12. E/AndroidRuntime(  293):     at paulscode.android.helloandroid.HelloAndroid.onCreate(HelloAndroid.java:18)
    13. E/AndroidRuntime(  293):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    14. E/AndroidRuntime(  293):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
    15. E/AndroidRuntime(  293):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
    16. E/AndroidRuntime(  293):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
    17. E/AndroidRuntime(  293):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
    18. E/AndroidRuntime(  293):     at android.os.Handler.dispatchMessage(Handler.java:99)
    19. E/AndroidRuntime(  293):     at android.os.Looper.loop(Looper.java:123)
    20. E/AndroidRuntime(  293):     at android.app.ActivityThread.main(ActivityThread.java:4627)
    21. E/AndroidRuntime(  293):     at java.lang.reflect.Method.invokeNative(Native Method)
    22. E/AndroidRuntime(  293):     at java.lang.reflect.Method.invoke(Method.java:521)
    23. E/AndroidRuntime(  293):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
    24. E/AndroidRuntime(  293):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
    25. E/AndroidRuntime(  293):     at dalvik.system.NativeStart.main(Native Method)
    26. W/ActivityManager(   60):   Force finishing activity paulscode.android.helloandroid/.HelloAndroid
    27. W/ActivityManager(   60): Activity pause timeout for HistoryRecord{44fcde90 paulscode.android.helloandroid/.HelloAndroid}
    28. W/ActivityManager(   60): Activity destroy timeout for HistoryRecord{44fcde90 paulscode.android.helloandroid/.HelloAndroid}
    29. I/Process (  293): Sending signal. PID: 293 SIG: 9
    30. I/ActivityManager(   60): Process paulscode.android.helloandroid (pid 293) has died.
    31. W/InputManagerService(   60): Window already focused, ignoring focus gain of: com.android.internal.view.IInputMethodClient$Stub$Proxy@44f63478
    Obviously the relevant message here is no implementation for the native method. The way it is referenced there does look a bit odd "paulscode/android/helloandroid/HelloAndroid;.sayHi ()", but I don't really have a working example to compare to see if that is a normal syntax. The only other causes I can think of are either a typo in my code somewhere or the native library somehow not being included in the APK or otherwise not being transferred to the AVD at run time.

    Hopefully this might help someone with more experience figure out what is wrong.
     
  5. paulscode

    paulscode Well-Known Member This Topic's Starter

    Joined:
    Mar 18, 2010
    Messages:
    86
    Likes Received:
    14
    Haha, so simple (I figured it would be). I totally forgot to load the native library from the Java portion (I even looked at the examples and still missed it). For reference, the working HelloAndroid.cpp looks like this:

    Code (Text):
    1. package paulscode.android.helloandroid;
    2.  
    3. import android.app.Activity;
    4. import android.os.Bundle;
    5. import android.widget.TextView;
    6.  
    7. public class HelloAndroid extends Activity
    8. {
    9.     @Override
    10.     public void onCreate( Bundle savedInstanceState )
    11.     {
    12.         super.onCreate( savedInstanceState );
    13.         TextView tv = new TextView( this );
    14.         tv.setText( sayHi() );
    15.         setContentView( tv );
    16.     }
    17.    
    18.     public native String sayHi();
    19.    
    20.     static
    21.     {
    22.         System.loadLibrary( "HelloAndroid" );
    23.     }
    24. }
     
  6. GIR

    GIR Well-Known Member

    Joined:
    Feb 14, 2010
    Messages:
    96
    Likes Received:
    10
    Nice too see you got if sussed
     

Share This Page

Loading...