第一个ndk程序 :
这里完成的功能是 用java调用C代码 来实现输出一个HelloWorld~
需要下载ndk -- 百度 , 下载安装后解压即可;
新建一个AndroidProject,然后新建一个jni包。包下新建一个JniTest类。
结构如下:
开始JniTest文件中代码如下:
package com.somnus.androidtest.jni; public class JniTest { public static native String helloWorldFromJNI(); }
布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.somnus.androidtest.MainActivity" > <TextView android:id="@+id/tv_hello_jni" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/tv_hello_jni" android:onClick="onAction" android:text="点击我调用JNI" /> </RelativeLayout>
Main文件代码:
package com.somnus.androidtest; import com.somnus.androidtest.jni.JniTest; import android.os.Bundle; import android.support.v7.app.ActionBarActivity; import android.view.View; import android.widget.TextView; public class MainActivity extends ActionBarActivity { private TextView tv_hello_jni; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv_hello_jni = (TextView) findViewById(R.id.tv_hello_jni); } public void onAction(View v) { String mStr = JniTest.helloWorldFromJNI(); tv_hello_jni.setText(mStr); } }
***********************进入正题:***********************
开始得到我们的jni文件 ----> .c .h 文件 以及.mk文件
1:开始生成我们的.h 文件。
步骤如下:
新建一个 launch configuration 左上角 图标 。 然后我这里命名为:AndroidNDKDemo
Location 中是jdk的javah.exe 路径;eg: C:\Program Files\Java\jdk1.8.0_25\bin\javah.exe (这是我的jdk路径)
Working Drectory : ${project_loc} 从Variables中选择来
Arguments : -classpath ${project_loc}/bin/classes -d ${project_loc}/jni jni ${java_type_name}
注意在选项卡 Refresh中勾上Refresh resources upon completion
common中 选中 External Tools
最后Apply;
此时就看见目录下多了一个jni文件夹 ;jni目录下有一个xxx_xx_xxx_.h文件
这时 , 在.h 中就是我们的JniTest中的方法 。然后我们新建一个对应的.c文件 将.h中的方法复制到.c 文件中 并不齐括号 注意不要复制JNIEXPORT
此时我的.h文件为:
com_somnus_androidtest_jni_JniTest.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class com_somnus_androidtest_jni_JniTest */ #ifndef _Included_com_somnus_androidtest_jni_JniTest #define _Included_com_somnus_androidtest_jni_JniTest #ifdef __cplusplus extern "C" { #endif /* * Class: com_somnus_androidtest_jni_JniTest * Method: helloWorldFromJNI * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_somnus_androidtest_jni_JniTest_helloWorldFromJNI (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif
com_somnus_androidtest_jni_JniTest.c
#include <jni.h> #include <string.h> jstring JNICALL Java_com_somnus_androidtest_jni_JniTest_helloWorldFromJNI( JNIEnv *env, jobject mString) { return (*env)->NewStringUTF(env, "HelloWorld! I am from JNI !"); }
新建Android.mk文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) #LOCAL_MODULE表示生成的库的名字,前面的lib和后缀名不用写 LOCAL_MODULE := HelloWorld LOCAL_SRC_FILES := com_somnus_androidtest_jni_JniTest.c include $(BUILD_SHARED_LIBRARY)
现在我们就开始编译代码
打开JniTest.java
还是打开External Tools Configurations ..
在new一个文件 。 Loaction 为ndk-build.com 的路径 (下载NDK解压的目录下)
也要注意Refresh中和Common中的配置
好了Run 。。。。
你将会看到 libs中新增了一个armeabi文件夹 目录下多了一个libHellowWorld.so文件
最后的目录结构:
到现在我们在回到我们的JniTest文件中 , 写一个调用方法;如下
JniTest.java
package com.somnus.androidtest.jni; public class JniTest { static{ //注意这里的名字: HelloWorld 是我们在mk文件中给定的名字 而不是libs下的so文件名 System.loadLibrary("HelloWorld"); } public static native String helloWorldFromJNI(); }
然后我们在运行 触发按钮 运行图:
ok! 到此结束~~