android NDk初步学习以及某些小问题的解决方法备忘 一

来源:互联网 发布:淘宝店铺的微淘在哪里 编辑:程序博客网 时间:2024/06/05 18:29

最近做android项目,终于用到了NDK。我本身太懒,碰不到的东西都不想去学习,等到问题出来了才有劲头去研究。虽然项目本身的JNI问题在网上七凑八凑的搞定了,但是感觉NDK的内容还是要从头系统的学习一下,所以这里在标题后面加了个一。这个“一”可能会不断的增加,也可能就会这么一直孤独下去了……

    现在开始记录一下初次学习的步骤吧。刚学习我也是去网上找了一篇博客,博客地址如下:(http://blog.csdn.net/redoffice/article/details/6654714)这篇博客里面的作者写的很清楚,也

特别适合我这种懒人的入门学习。但是完全照着他的去做并不能走完一个流程,大部分原因应

该是jdk,ndk的版本导致的。这里我们还是以他的为基础,用最新的ndk(我的是ndk8)吧整

个流程再走一遍,顺便记录下某些问题的解决方法。


   首先,建立android工程,工程中的MainActivity内容如下(这里面的代码还是上文提到那篇

博客的代码,暂时不纠结这个,主要还是把流程走通):

   

    @Override    public void onCreate(Bundle savedInstanceState)    {        super.onCreate(savedInstanceState);        TextView  myTextView = new TextView(this);        myTextView.setText( stringTestNdk() );        setContentView(myTextView);    }    public native String  stringTestNdk();    public native String  stringTestNdk2();    static {        System.loadLibrary("testNDK");    }<span style="font-family:Arial, Helvetica, sans-serif;font-size:24px;"><span style="font-size: 18px; white-space: normal;"></span></span>

    其中 System.loadLibrary("testNDK");是加载testNDK库文件(全名为libtestNDK.so)。两

个native方法是我们要在C/C++中实现的的native方法。


然后,打开cmd,进入工程下面输入javah -classpath bin/classes -d ndk com.exm.helloword.MainActivity

(这里注意原博客里面没有加入bin后面的classes,但是那样执行可能因为jdk版本问题会出错)。这样就生成了

一个.h文件。这个头文件貌似没用到,但是还是生成,待会写c/C++文件的时候可以吧函数名拷过去。

头文件的内容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_exm_helloword_MainActivity */#ifndef _Included_com_exm_helloword_MainActivity#define _Included_com_exm_helloword_MainActivity#ifdef __cplusplusextern "C" {#endif/* * Class:     com_exm_helloword_MainActivity * Method:    stringTestNdk * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk  (JNIEnv *, jobject);/* * Class:     com_exm_helloword_MainActivity * Method:    stringTestNdk2 * Signature: ()Ljava/lang/String; */JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk2  (JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

这里生成的头文件默认生成在工程目录下的ndk目录下,我在工程下面新建了一个jni目录,

把头文件拷贝到到jni目录中,看里面的两个方法,命名规则是 包名+类名+函数名,括号里的两个参数是默认的。

再然后,在jni目录下新建一个testNSK.cpp的C++文件,里面的内容我直接把上文提到博客里面

的c内容加入进去,代码如下:

#include <string.h>#include <jni.h>JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk(JNIEnv *env, jobject obj){ return (*env)->NewStringUTF(env, "Hello Test Little T !");}

编写完成该C++文件以后,在jni目录下新建一个mk文件,命名为Android.mk内容如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE:= testNDKLOCAL_SRC_FILES := testNDK.cppinclude $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)

编写完mk文件后 用ndk编译上述文件,以便生成so文件。编译过程如下(适合ndk8以上,不用安装配置cygwin):

在cmd中进入到工程的jni目录下,输入ndk命令D:\android\ndk-bulid(我没有配置环境变量,切ndk在该

目录下所以输入的是整个路径名称加上ndk命令)

编译过程到这里就算是结束了。但是我碰到了两个问题:

(1)the mangling of ‘va_list’ has changed in GCC4.4

在mk文件中加入 LOCAL_CFLAGS = -Wno-psabi,修改后mk文件如下:

LOCAL_PATH := $(call my-dir)include $(CLEAR_VARS)<span style="color:#FF0000;">LOCAL_CFLAGS = -Wno-psabi</span>LOCAL_MODULE:= testNDKLOCAL_SRC_FILES := testNDK.cppinclude $(BUILD_SHARED_LIBRARY) 

(2) base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}':

问题是原博客的是c文件,我写的是c++文件,所以要把testNDK.cpp的内容改为:

#include <string.h>#include <jni.h>extern "C" {JNIEXPORT jstring JNICALL Java_com_exm_helloword_MainActivity_stringTestNdk(JNIEnv *env, jobject obj){ <return env->NewStringUTF("Hello Test Little T !");}<span style="color:#FF0000;">}

修改完成再运行ndk命令,便可在工程下发现多了一个obj包,包里面有个local文件夹,

可以找到libtestNDK.so的包。然后运行工程,便可输出如下信息。"Hello Test Little T !"


好了,到这里算是吧流程走完了,但是里面的很多概念性的东西还不是很了解,

当然上文提到的博客里面有比较详细明了的说明,更细节的和深入的内容有

待继续去学习,希望那个“一”不会孤独下去。


0 0
原创粉丝点击