第一个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++代码吧。




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 3岁宝宝有蛀牙了怎么办 三岁宝宝夜惊怎么办 小班孩子跳舞不好好跳怎么办 15个月宝宝拉稀怎么办 孩子学习不认真该怎么办 孩子学习不自觉该怎么办 孩子学习压力大该怎么办 分手发信息不回怎么办 两岁宝宝不会回答问题怎么办 分手了我还想他怎么办 两岁宝宝特别不听话怎么办 2岁宝宝争东西怎么办 两岁宝宝钙吸收不好怎么办 1岁宝宝害羞胆小怎么办 2岁宝宝害羞胆小怎么办 6个月的宝宝胆小怎么办 3岁半宝宝很胆小怎么办 分手了想他了怎么办 分手了还想联系怎么办 2岁多宝宝不长肉怎么办 2个月宝宝尿裤子怎么办 四岁宝宝脾气大怎么办 两周宝宝换奶粉怎么办 两周半宝宝不喝奶粉怎么办 2岁半宝宝太调皮怎么办 2岁宝宝晚上睡觉晚怎么办 三周岁半宝宝入园后不合群怎么办 数学懒于思考的孩子怎么办 2岁宝宝爱哭不讲道理怎么办 孩子不讲道理一直哭怎么办 白天不烧晚上烧怎么办 两岁宝宝出虚汗怎么办 两岁宝宝出水痘怎么办 两岁宝宝爱看手机怎么办 两岁宝宝太好动怎么办 五岁宝宝不会数数怎么办 四岁宝宝算数不好怎么办 两个月宝宝体内有火怎么办 两个月宝宝有火怎么办 2岁宝宝起眼屎怎么办 一周岁的宝宝皮肤过敏怎么办