第一个NDK程序
来源:互联网 发布:手机以旧换新软件 编辑:程序博客网 时间:2024/06/05 12:49
之前写了第一个JNI程序,有翻译了一篇NDK的入门教程,今天从头到尾自己写了一个。
环境:linux+ndk r6
开始之前:java和ndk的环境变量已经设置好
目标:一个简单的例子,从c中传给java int数组和字符串数组
开始:
新建一个项目,名称为FirstNDK
一个包是package com.linc.FirstNDK;放activity
另一个是package com.linc.lib;放lib文件,主要处理jni
布局:两个按钮+一个textview
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" ><Buttonandroid:id="@+id/btnOne" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="int Array!"/><TextView android:id="@+id/Result" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Result:" /><Buttonandroid:id="@+id/btnTwo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="string Array!"/> </LinearLayout>package com.linc.lib包下新建一个类FirstLib
package com.linc.lib;public class FirstLib {// Native implementation static { System.loadLibrary("FirstLib"); } //传递数组public static native int[] intMethod();//传递字符串数组public static native String[] stringMethod();}这里主要有两个本地方法,
下面用它生成jni的头文件:用终端来到项目bin目录(前提是FirstLib这个类已经编译完成),
[linc@localhost bin]$ javah -jni com.linc.lib.FirstLib项目中新建一个jni目录,用来存放jni相关文件,并把刚刚生成的头文件放进去
[linc@localhost bin]$ mv com_linc_lib_FirstLib.h ../jni在jni中新建一个c文件与上面的对应叫FirstLib.c,
#include "com_linc_lib_FirstLib.h"const static int length=10;//传递整型数组JNIEXPORT jintArray JNICALL Java_com_linc_lib_FirstLib_intMethod (JNIEnv *env, jclass obj){jintArray array;//数组array=(*env)->NewIntArray(env,10);int i=1;for(;i<=10;++i){(*env)->SetIntArrayRegion(env,array,i-1,1,&i);}//获取数组长度int len=(*env)->GetArrayLength(env,array);//获得数组中的所有元素jint* elems=(*env)->GetIntArrayElements(env,array,0);return array;}//字符串数组JNIEXPORT jobjectArray JNICALL Java_com_linc_lib_FirstLib_stringMethod (JNIEnv *env, jclass obj){jclass class=(*env)->FindClass(env,"java/lang/String");jobjectArray string=(*env)->NewObjectArray(env,(jsize)length,class,0);jstring jstr;char* _char[]={"my ","name ","is ","linc!!","正在","学习","JNI","和","NDK","技术!"};int i=0;for(;i<length;++i){jstr=(*env)->NewStringUTF(env,_char[i]);(*env)->SetObjectArrayElement(env,string,i,jstr);}return string;}
在jni目录下新建一个mk文件,Android.mk
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := FirstLibLOCAL_SRC_FILES := FirstLib.cinclude $(BUILD_SHARED_LIBRARY)
好,下面将其编译成共享库:回到项目目录
[linc@localhost FirstNDK]$ cd ..[linc@localhost FirstNDK]$ ndk-buildCompile thumb : FirstLib <= FirstLib.cSharedLibrary : libFirstLib.soInstall : libFirstLib.so => libs/armeabi/libFirstLib.so
下面在activity中调用之:
package com.linc.FirstNDK;import java.io.UnsupportedEncodingException;import com.linc.lib.FirstLib;import com.linc.lib.PersonalInfo;import android.app.Activity;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class FirstNDK extends Activity {TextView textResult; Button buttonOne; Button buttonTwo; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textResult = (TextView) findViewById(R.id.Result); buttonOne = (Button) findViewById(R.id.btnOne); buttonOne.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint[] nums=FirstLib.intMethod();for(int i=0;i<nums.length;++i){textResult.append(" "+nums[i]);}}}); buttonTwo = (Button) findViewById(R.id.btnTwo); buttonTwo.setOnClickListener(btnTwo_Click); } private OnClickListener btnTwo_Click = new OnClickListener() { public void onClick(View v) { String[] string=FirstLib.stringMethod(); for(int i=0;i<string.length;++i) { try { string[i]=new String(string[i].getBytes("gb2312"),"GBK"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } textResult.append(" "+string[i]); } } };}最后就可以运行看效果了!
ndk的使用,首先要具备jni的相关知识,在本blog中有相关记载。
希望大家用ndk来开发游戏时,玩的开心!
后记:
1.ndk 未找到。。。类的错误。
今天发现这个错误,主要是因为项目bin路径下还有一层classes。如下处理就可以了:
~/workspace/TestNDK/bin$ javah -classpath ./classes -d ./jni com.linc.lib.FirstLib
2.loadlibrary相关
Android.mk 可以这样写(摘自cocos2d-x中的demo):
LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := game_sharedLOCAL_MODULE_FILENAME := libgameLOCAL_SRC_FILES := hellocpp/main.cpp \ ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorldScene.cpp \ ../../Classes/GameOverScene.cpp LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static include $(BUILD_SHARED_LIBRARY)$(call import-module,CocosDenshion/android)$(call import-module,cocos2dx)LOCAL_MODULE 是game_shared,如果没有定义LOCAL_MODULE_FILENAME,那么编译出来的so就是libgame_shared.so,
而在java文件中load时就必须要
static { System.loadLibrary("game_shared"); }有趣的是,定义LOCAL_MODULE_FILENAME为libgame后,编译出来的so当然是libgame.so了,而java中load “game”就可以了。
3.NDK r7之后直接对编译的支持
在整理NDK r7的特性时,直接提供对编译的支持,在windows下就不用cygwin了。
现在我已经使用r9b了,项目右键--->Android Tools--->Add Native Support...
你会发现帮你添加了jni的文件夹,并且项目属性中在Builders里面有多了两项,一个是CDT Builder,一个是Scanner Configuration Builder。
更贴心的,属性都为你设置好了,直接添加编辑你的C、C++代码吧。
- 第一个NDK程序
- 第一个NDK程序
- 第一个NDK程序
- NDK第一个程序
- 编写第一个NDK程序
- 创建第一个NDK程序
- 第一个NDK程序 MyFirstNDK_app
- 编写第一个NDK程序
- 我的第一个NDK程序
- Android Studio运行第一个NDK程序
- Android studio开发NDK,第一个NDK程序教程
- Android NDK学习教程(一)--第一个NDK程序
- Android 第一个NDK
- Android 我的第一个 NDK 程序 (AndroidStudio)
- 第一个NDK小程序之两个数的加法
- 如何编写第一个成功的Android NDK程序
- Android NDK-r5 成功运行编译运行第一个NDK程序
- 搭建Window环境下android NDK开发环境——编译第一个NDK程序
- JavaScript 消息框
- 结合工具来实现敏捷开发 - 12
- List的特殊操作
- IT男士专用餐单(转自csdn PP_LP专栏)
- 给老爸老妈的100个长寿秘诀 完了 看看有好处(zt)
- 第一个NDK程序
- IPhone os-----基本知识(学习iphone的请进)
- IE9报“DOM Exception: INVALID_CHARACTER_ERR (5)”错误的原因及解决办法
- 编程笔记(2)
- PHPEclipse+zend debugger调试环境配置
- 如何发布iPhone程序
- JavaScript 函数
- 物品装箱问题(文件名:box.c/cpp/pas)
- 构建自己的Linux 之三 初步完善(提供网络功能等)