官术网_书友最值得收藏!

Writing a Hello NDK program

With the environment set up, let's start writing the code in NDK. This recipe walks through a Hello NDK program.

Getting ready

The NDK development environment needs to be set up properly before starting to write the Hello NDK program. Please refer to previous recipes in this chapter, depending upon the platform of your choice.

How to do it…

Follow these steps to write, compile, and run the Hello NDK program:

  1. Start Eclipse, and select File | New | Android Project. Enter HelloNDK as the value for Project Name. Select Create new project in workspace. Then click on Next:
    How to do it…
  2. In the next window, select an Android version that you want to target. Usually, the latest version is recommended. Then click on Next.
  3. In the next window, specify your package name as cookbook.chapter1. Select the Create Activity box, and specify the name as HelloNDKActivity. Set the value for Minimum SDK as 5 (Android 2.0). Click on Finish:
    How to do it…
  4. In the Eclipse package explorer, right-click on the HelloNDK project, and select New | Folder. Enter the name jni in the pop-up window, then click on Finish:
    How to do it…
  5. Right-click on the newly-created jni folder under the HelloNDK project. Select New | File, enter hello.c as the value for File name, then click on Finish. Type the following code in the hello.c file:
    #include <string.h>
    #include <jni.h>
    
    jstring 
    Java_cookbook_chapter1_HelloNDKActivity_naGetHelloNDKStr(JNIEnv* pEnv,  jobject pObj)
    {
        return (*pEnv)->NewStringUTF(pEnv, "Hello NDK!");
    }
  6. Right-click on the jni folder. Select New | File, enter Android.mk as the value for File name, then click on Finish. Type the following code in the Android.mk file:
    LOCAL_PATH := $(call my-dir)
    include $(CLEAR_VARS)
    LOCAL_MODULE    := hello
    LOCAL_SRC_FILES := hello.c
    include $(BUILD_SHARED_LIBRARY)
  7. Start a terminal, go to the jni folder, and type ndk-build to build the hello.c program as a native library.
  8. Edit the HelloNDKActivity.java file. The file should contain the following content:
    public class HelloNDKActivity extends Activity {
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            TextView tv = new TextView(this);
            tv.setTextSize(30);
            tv.setText(naGetHelloNDKStr());
            this.setContentView(tv);
        }
        public native String naGetHelloNDKStr();
        static {
            System.loadLibrary("hello");
        }
    }
  9. Right-click on the HelloNDK project in Eclipse. Select Run As | Android Application. Your Android phone or emulator will be displayed with something similar to the following screenshot:
    How to do it…

How it works…

This recipe demonstrated how to write a Hello NDK program on Android.

  • Native code: The Hello NDK program consists of both the native C code and Java code. The native function naGetHelloNDKStr returns the Hello NDK string to the caller, as indicated in both the native code function definition and Java code method declaration. The native function name must follow a specific pattern for a package name, class name, and method name. The package and class name must agree with the package and class name of the Java class from which the native method is called, while the method name must be the same as the method name declared in that Java class.

    This helps the Dalvik VM to locate the native function at runtime. Failing to follow the rule will result in UnsatisfiedLinkError at runtime.

    The native function has two parameters, which are standard for all native functions. Additional parameters can be defined based on needs. The first parameter is a pointer to JNIEnv , which is the gateway to access various JNI functions. The meaning of the second parameter depends on whether the native method is a static or an instance method. If it's a static method, the second parameter is a reference to the class where the method is defined. If it's an instance method, the second parameter is a reference to the object on which the native method is invoked. We will discuss JNI in detail in Chapter 2, Java Native Interface.

  • Compilation of the native code: The Android NDK build system frees developers from writing makefile. The build system accepts an Android.mk file, which simply describes the sources. It will parse the file to generate makefile and do all the heavy lifting for us.

    We will cover details of how to write the Android.mk file or even write our own makefile in Chapter 3, Build and Debug NDK Applications.

    Once we compile the native code, a folder named libs will be created under our project and a libhello.so library will be generated under the armeabi subdirectory.

  • Java code: Three steps are followed to call the native method:
    1. Load the native library: This is done by calling System.loadLibrary("hello"). Note that instead of libhello, we should use hello. The Dalvik VM will fail to locate the library if libhello is specified.
    2. Declare the method: We declare the method with a native keyword to indicate that it is a native method.
    3. Invoke the method: We call the method just like any normal Java method.

There's more…

The name of a native method is lengthy and writing it manually is error-prone. Fortunately, the javah program from JDK can help us generate the header file, which includes the method name. The following steps should be followed to use javah:

  1. Write the Java code, including the native method definition.
  2. Compile the Java code and make sure the class file appears under the bin/classes/ folder of our project.
  3. Start a terminal and go to the jni folder, and enter the following command:
    $ javah -classpath ../bin/classes –o <output file name> <java package name>.<java class anme>
    

    In our HelloNDK example, the command should be as follows:

    $ javah -classpath ../bin/classes –o hello.h cookbook.chapter1.HelloNDKActivity
    

    This will generate a file named hello.h with its function definition as follows:

    JNIEXPORT jstring JNICALL Java_cookbook_chapter1_HelloNDKActivity_naGetHelloNDKStr
      (JNIEnv *, jobject);
主站蜘蛛池模板: 松江区| 修文县| 泰州市| 铅山县| 绥化市| 荣成市| 潮州市| 宁南县| 辽中县| 通海县| 遂川县| 桃园市| 凤阳县| 武穴市| 琼海市| 西盟| 资溪县| 吴忠市| 保靖县| 和平区| 郑州市| 高陵县| 安图县| 鹤壁市| 井冈山市| 扶沟县| 蕲春县| 长乐市| 安陆市| 林周县| 佛坪县| 安岳县| 鹤庆县| 昭平县| 崇左市| 进贤县| 赣榆县| 安新县| 峨眉山市| 闽侯县| 罗甸县|