Android NDK 笔记

来源:互联网 发布:淘宝卖家记账软件 编辑:程序博客网 时间:2024/06/08 19:55

一:NDK坏境搭建:

1.下载NDK:http://developer.android.com/tools/sdk/ndk/index.html
2.配置环境变量:

配置好可以cmd测试一下:

二:新建android项目(HelloNdk):

1.编写native方法

MainActivity.java

package com.example.hellondk;import android.app.Activity;import android.os.Bundle;public class MainActivity extends Activity {public static native String getStringFromC();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}}

2.cmd 到项目根目录执行 Javah 命令,生成头文件

D:\Android\workspace\HelloNdk>javah -classpath bin/classes;D:\java\sdk\platforms\android-16\android.jar -d jni com.example.hellondk.MainActivity

2.1,按F5刷新项目, 会多出一个jni文件夹里面会有个.h的头文件

生成前 生成后





2.2,创建hello.c文件



2.3,编写hello.c文件


#include <stdio.h>#include <stdlib.h>#include "com_example_hellondk_MainActivity.h"JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getStringFromC(JNIEnv * env, jclass jclazz) {return (*env)->NewStringUTF(env, "Hello from JNI !");};

2.4,在jni目录下新建Android.mk文件


2.5,编辑Android.mk文件(*注:LOCAL_MODULE:模块的名字,LOCAL_SRC_FILES:编译的源代码文件

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := helloLOCAL_SRC_FILES := hello.cinclude $(BUILD_SHARED_LIBRARY)


2.6,cmd 到项目根目录执行 ndk-build命令,生成.so文件


2.7,F5刷新项目,多出obj文件夹


2.8,修改MainActivity.java

package com.example.hellondk;import android.app.Activity;import android.os.Bundle;import android.widget.TextView;public class MainActivity extends Activity {public static native String getStringFromC();static{ System.loadLibrary("hello");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv =(TextView) findViewById(R.id.tv);tv.setText(getStringFromC());}}


2.9,运行项目


三:eclipse配置ndk环境和打印log信息

1.ndk自动编译

右键项目->Properties->Builders->New->新建一个Builder







2.eclipse配置ndk环境和打印log信息

可以参考
D:\java\android-ndk-r10\samples\native-media\jni\native-media-jni.c
#include <android/log.h>#define TAG "NativeMedia"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)


D:\java\android-ndk-r10\samples\native-media\jni\Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE    := helloLOCAL_SRC_FILES := hello.c# for loggingLOCAL_LDLIBS    += -lloginclude $(BUILD_SHARED_LIBRARY)

log.h详细参考一下
D:\java\android-ndk-r10\platforms\android-16\arch-arm\usr\include\android\log.h

示例代码:hello.c
#include <stdio.h>#include <stdlib.h>#include "com_example_hellondk_MainActivity.h"#include <android/log.h>#define TAG "TestTag"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getStringFromC(JNIEnv * env, jclass jclazz) {LOGV("测试Log打印日志!");return (*env)->NewStringUTF(env, "Hello from JNI 成功 !");};
运行控制台输出


四.jni交互处理

1.jni交互处理之字符串处理

1.1,JNI帮助文档:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

1.2,示例

MainActivity.java
package com.example.hellondk;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.widget.TextView;public class MainActivity extends Activity {public static native void updateFile(String path);public static native String getStringFromC();static{ System.loadLibrary("hello");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv =(TextView) findViewById(R.id.tv);tv.setText(getStringFromC());String path = Environment.getExternalStorageDirectory().getAbsolutePath();;updateFile(path+"/boys.txt");}}


hello.c
#include <stdio.h>#include <stdlib.h>#include "com_example_hellondk_MainActivity.h"#include <android/log.h>#define TAG "TestTag"#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, TAG, __VA_ARGS__)JNIEXPORT jstring JNICALL Java_com_example_hellondk_MainActivity_getStringFromC(JNIEnv * env, jclass jclazz) {LOGV("测试Log打印日志!");return (*env)->NewStringUTF(env, "Hello from JNI 成功 !");}JNIEXPORT void JNICALL Java_com_example_hellondk_MainActivity_updateFile(JNIEnv * env, jclass jclazz, jstring path) {//生成native的char的指针const char*file_path = (*env)->GetStringUTFChars(env, path, NULL);if (file_path != NULL) {LOGV("from c file_path %s", file_path);}//打开文件FILE*file = fopen(file_path, "a+");if (file != NULL) {LOGV("from c open file succes");}//写入文件char data[] = "I am a boy";int count = fwrite(data, strlen(data), 1, file);if (count > 0) {LOGV("from c write file succes");}//关闭文件if (file != NULL) {fclose(file);}//释放资源(*env)->ReleaseStringUTFChars(env, path, file_path);}
*注:android读写sd卡权限设置
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />

2.jni交互处理之数组处理(上)

MainActivity.java
package com.example.hellondk;import android.app.Activity;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.widget.TextView;public class MainActivity extends Activity {public static native void updateFile(String path);public static native int[] updateIntArray(int[] data);public static native String getStringFromC();static {System.loadLibrary("hello");}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);TextView tv = (TextView) findViewById(R.id.tv);tv.setText(getStringFromC());updateFile(Environment.getExternalStorageDirectory().getAbsolutePath() + "/boys.txt");int[] data = { 1, 2, 3, 4, 5 };int[] resuilt = updateIntArray(data);for (int i = 0; i < resuilt.length; i++) {Log.i("TestTag", "i=" + resuilt[i]);}}}



hello.c
JNIEXPORT jintArray JNICALL Java_com_example_hellondk_MainActivity_updateIntArray  (JNIEnv *env, jclass jclazz, jintArray array){jint nativeArray[5];(*env)->GetIntArrayRegion(env,array,0,5,nativeArray);int j;for ( j= 0; j < 5; j++) {nativeArray[j]+=5;LOGV("from c int %d",nativeArray[j]);}(*env)->SetIntArrayRegion(env,array,0,5,nativeArray);return array;};

3.jni交互处理之数组处理(下)

JNIEXPORT jintArray JNICALL Java_com_example_hellondk_MainActivity_updateIntArray  (JNIEnv *env, jclass jclazz, jintArray array){//生成数组的指针<span style="white-space:pre"></span>jint* data = (*env)->GetIntArrayElements(env,array,NULL);<span style="white-space:pre"></span>jsize len = (*env)->GetArrayLength(env,array);<span style="white-space:pre"></span>int j;<span style="white-space:pre"></span>for ( j= 0; j < len; j++) {<span style="white-space:pre"></span>data[j]+=3;<span style="white-space:pre"></span>LOGV("from c int %d",data[j]);<span style="white-space:pre"></span>}<span style="white-space:pre"></span>//释放相关的资源<span style="white-space:pre"></span>(*env)->ReleaseIntArrayElements(env,array,data,0);<span style="white-space:pre"></span>return array;};

通过jni头文件做参考:D:\java\android-ndk-r10\platforms\android-16\arch-arm\usr\include\jni.h


4.Eclipse自动生成头文件设置

Run->Exteranl Tools->Exteranl Tools Configurations 






-classpath ${project_loc}\bin\classes;D:\java\sdk\platforms\android-16\android.jar -d ${project_loc}\jni -jni ${java_type_name}

5.编辑C/C++ Eclipse 代码提示




签名:E:\workspace\HelloKitty>javap -classpath bin\classes -s -p com.example.hellokitty.MainActivity





*


0 0
原创粉丝点击